From 329a79234449dcadbaf0aa7c09a3b74fea834746 Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Fri, 17 Jun 2005 17:07:46 +0000 Subject: [PATCH] window-afsifs-20050617 Updates to the afsifs-20050615 DELTA. * Fix the build system * Reformat the code * Update docs --- README-NT | 17 +- doc/txt/winnotes/afs-changes-since-1.2.txt | 14 + doc/txt/winnotes/msi-deployment-guide.txt | 2 +- src/WINNT/afsd/afsd_service.c | 28 +- src/WINNT/afsd/afsdifs.c | 1457 ++++---- src/WINNT/afsd/cm_callback.c | 12 +- src/WINNT/afsd/cm_ioctl.c | 57 +- src/WINNT/afsd/cm_vnodeops.c | 23 +- src/WINNT/afsd/rawops.c | 667 ++-- src/WINNT/afsrdr/afsrdr.c | 3463 ++++++++++---------- src/WINNT/afsrdr/ifs_rpc.c | 2288 ++++++------- src/WINNT/afsrdr/ifs_rpc.h | 28 +- src/WINNT/afsrdr/kif.h | 4 +- src/WINNT/client_config/drivemap.cpp | 131 +- src/config/NTMakefile.amd64_w2k | 10 +- src/config/NTMakefile.i386_nt40 | 14 +- src/config/NTMakefile.i386_w2k | 10 +- src/sys/pioctl_nt.c | 65 +- 18 files changed, 4183 insertions(+), 4107 deletions(-) diff --git a/README-NT b/README-NT index 522a5ad7f..8134ea873 100644 --- a/README-NT +++ b/README-NT @@ -71,7 +71,7 @@ The following Microsoft SDK is required: The following Microsoft DDK is required: - Microsoft Windows Server 2003 DDK + Microsoft Windows Server 2003 SP1 DDK available via a MSDN subscription or via free CD http://www.microsoft.com/whdc/devtools/ddk/orderddkcd.mspx @@ -180,6 +180,11 @@ These files come from the following Microsoft DDKs/SDKs: netcfgn.h, netcfgx.h: Windows XP/2003 DDK - inc/wxp/ +If you are interested in experimenting with the IFS you must purchase from +Microsoft a copy of the Windows 2003 SP1 IFS Kit. + + http://www.microsoft.com/whdc/devtools/ifskit/default.mspx + STEP D. Configure NTBUILD.BAT. @@ -200,7 +205,8 @@ must be defined to match your configuration: NTDDKDIR: Set the short name of the directory containing the npapi.h file - AFSROOT: Set to the short name of the OpenAFS Base directory + AFSROOT: Set to the short name of the OpenAFS Base directory. This + cannot be set to a UNC path. STEP E. Set version and installation options (optional) @@ -211,7 +217,7 @@ from: http://grand.central.org/dl/cellservdb/CellServDB then copy it to %AFSROOT%\src\WINNT\install\NSIS and name it afsdcell.ini -Edit file %AFSROOT%\src\config\NTMakefile.i386_nt40 +Edit file %AFSROOT%\src\config\NTMakefile.i386_w2k AFSPRODUCT_VER_MAJOR - Version Major Number AFSPRODUCT_VER_MINOR - Version Minor Number AFSPRODUCT_VER_PATCH - Version Patch Number @@ -284,7 +290,7 @@ STEP F. Begin the build nmake /f NTMakefile clean -(5) Build the complete Windows NT/2000 development environment. +(5) Build the complete Windows 2000/XP/2003 development environment. nmake /f NTMakefile install @@ -293,6 +299,9 @@ behavior is normal; the build process is successful as long as the build process doesn't terminate with an error ("nmake.exe return code 0x2") and it displays 'Build Finished Successfully'. +(6) [IFS only] Open a DDK/IFS Build Environment command window, change + to the src\WINNT\afsrdr directory, and execute the "build" command. + STEP G. Install NSIS 2.0 (optional). diff --git a/doc/txt/winnotes/afs-changes-since-1.2.txt b/doc/txt/winnotes/afs-changes-since-1.2.txt index 1f0a8d6cc..8c8f9f1cb 100644 --- a/doc/txt/winnotes/afs-changes-since-1.2.txt +++ b/doc/txt/winnotes/afs-changes-since-1.2.txt @@ -1,3 +1,17 @@ +Since 1.3.84: + * Eric William's IFS redirector has been checked into the source + tree. This code is experimental at the current time and is not + being incorporated into binary releases. Instructions for building + from sources are found in the top-level README-NT file. + + * Modify integrated login so that it does not enter an infinite + loop if the service is not set to auto start. + + * Added asetkey.exe used to set a Kerberos 5 key for use by the + AFS server daemons + + * Added uninstall.exe to Wix installation + Since 1.3.83: * Changes to the algorithms used to wake threads when they are diff --git a/doc/txt/winnotes/msi-deployment-guide.txt b/doc/txt/winnotes/msi-deployment-guide.txt index 61a6cc75a..63cf941df 100644 --- a/doc/txt/winnotes/msi-deployment-guide.txt +++ b/doc/txt/winnotes/msi-deployment-guide.txt @@ -640,7 +640,7 @@ OpenAFS for Windows Registry : 'reg_freekey5' Root : 2 Key : 'SOFTWARE\OpenAFS\Client\Freelance\Symlinks' - Name : '0' + Name : '1' Value : '.athena:.athena.mit.edu.' Component : 'rcm_FreelanceKeys' diff --git a/src/WINNT/afsd/afsd_service.c b/src/WINNT/afsd/afsd_service.c index ad8614f8c..73bebb39e 100644 --- a/src/WINNT/afsd/afsd_service.c +++ b/src/WINNT/afsd/afsd_service.c @@ -449,20 +449,20 @@ static void MountGlobalDrives(void) #ifndef AFSIFS for ( ; dwRetry < MAX_RETRIES; dwRetry++) - { - NETRESOURCE nr; - memset (&nr, 0x00, sizeof(NETRESOURCE)); - - sprintf(szAfsPath,"\\\\%s\\%s",cm_NetbiosName,szSubMount); - - nr.dwScope = RESOURCE_GLOBALNET; /* ignored parameter */ - nr.dwType=RESOURCETYPE_DISK; - nr.lpLocalName=szDriveToMapTo; - nr.lpRemoteName=szAfsPath; - nr.dwDisplayType = RESOURCEDISPLAYTYPE_SHARE; /* ignored parameter */ - nr.dwUsage = RESOURCEUSAGE_CONNECTABLE; /* ignored parameter */ - - dwResult = WNetAddConnection2(&nr,NULL,NULL,0); + { + NETRESOURCE nr; + memset (&nr, 0x00, sizeof(NETRESOURCE)); + + sprintf(szAfsPath,"\\\\%s\\%s",cm_NetbiosName,szSubMount); + + nr.dwScope = RESOURCE_GLOBALNET; /* ignored parameter */ + nr.dwType=RESOURCETYPE_DISK; + nr.lpLocalName=szDriveToMapTo; + nr.lpRemoteName=szAfsPath; + nr.dwDisplayType = RESOURCEDISPLAYTYPE_SHARE; /* ignored parameter */ + nr.dwUsage = RESOURCEUSAGE_CONNECTABLE; /* ignored parameter */ + + dwResult = WNetAddConnection2(&nr,NULL,NULL,0); afsi_log("GlobalAutoMap of %s to %s %s (%d)", szDriveToMapTo, szSubMount, (dwResult == NO_ERROR) ? "succeeded" : "failed", dwResult); if (dwResult == NO_ERROR) { diff --git a/src/WINNT/afsd/afsdifs.c b/src/WINNT/afsd/afsdifs.c index 4e1ef48f3..0efedbe1f 100644 --- a/src/WINNT/afsd/afsdifs.c +++ b/src/WINNT/afsd/afsdifs.c @@ -35,43 +35,42 @@ /****************************/ /* parameters, macros, etc. */ /****************************/ -#define IFSL_SUCCEEDED(st) (!(st & IFSL_FAIL_BASE)) -#define MAP_RETURN(code) if (code) return ifs_MapCmError(code); - /* defined in multiple places (search source) */ -#define BUF_FILEHASH(fidp) ((((fidp)->vnode+((fidp)->unique << 13) + ((fidp)->unique >> (32-13)) \ - +(fidp)->volume+(fidp)->cell) \ +#define IFSL_SUCCEEDED(st) (!(st & IFSL_FAIL_BASE)) +#define MAP_RETURN(code) if (code) return ifs_MapCmError(code); + /* defined in multiple places (search source) */ +#define BUF_FILEHASH(fidp) ((((fidp)->vnode+((fidp)->unique << 13) + ((fidp)->unique >> (32-13)) \ + +(fidp)->volume+(fidp)->cell) \ /*& 0xffffffff*/)) -#define ROOTPATH "\\" -//#define ROOTPATH "\\CITI.UMICH.EDU" -#define TRANSFER_BUF_SIZE (2*1024*1024) -#define SCPL_LOCK EnterCriticalSection(&scp_list_lock); -#define SCPL_UNLOCK LeaveCriticalSection(&scp_list_lock); -#define MAX_USERS 32 +#define ROOTPATH "\\" +#define TRANSFER_BUF_SIZE (2*1024*1024) +#define SCPL_LOCK EnterCriticalSection(&scp_list_lock); +#define SCPL_UNLOCK LeaveCriticalSection(&scp_list_lock); +#define MAX_USERS 32 /****************************/ /* structs */ /****************************/ struct user_map_entry /* how we keep users straight. total of MAX_USERS of these */ - { - LARGE_INTEGER id; /* internal id created by kernel */ - cm_user_t *creds; /* global (thread-specific) var userp is set to this */ - }; - -struct scp_status /* one for each unique file in afs */ - { - struct scp_status *next; /* stored in a global chain in a chain locked by SCPL_[UN]LOCK */ - cm_scache_t *scp; /* file handle used with cm_ fns */ - ULONG fid; /* internal id generated by BUF_FILEHASH from AFS's 128-bit FID */ - }; +{ + LARGE_INTEGER id; /* internal id created by kernel */ + cm_user_t *creds; /* global (thread-specific) var userp is set to this */ +}; + +struct scp_status /* one for each unique file in afs */ +{ + struct scp_status *next; /* stored in a global chain in a chain locked by SCPL_[UN]LOCK */ + cm_scache_t *scp; /* file handle used with cm_ fns */ + ULONG fid; /* internal id generated by BUF_FILEHASH from AFS's 128-bit FID */ +}; typedef struct scp_status scp_status_t; struct readdir_context /* temporary struct, allocated as necessary, for cm_Apply callback */ - { - char *matchString; /* for matching against */ - char *buf, *buf_pos; /* filling buffer to length, currently at buf_pos */ - ULONG length; - ULONG count; /* number of entries packed so far */ - }; +{ + char *matchString; /* for matching against */ + char *buf, *buf_pos; /* filling buffer to length, currently at buf_pos */ + ULONG length; + ULONG count; /* number of entries packed so far */ +}; typedef struct readdir_context readdir_context_t; @@ -93,125 +92,125 @@ scp_status_t *scp_list_head = NULL; /****************************/ char *IfslErrorToText(unsigned long ifsl) { -switch (ifsl) - { - case IFSL_SUCCESS: - return "success"; - case IFSL_DOES_NOT_EXIST: - return "does not exist"; - case IFSL_NOT_IMPLEMENTED: - return "not implemented"; - case IFSL_END_OF_ENUM: - return "end of enum"; - case IFSL_CANNOT_MAKE: - return "cannot make"; - case IFSL_END_OF_FILE: - return "end of file"; - case IFSL_NO_ACCESS: - return "no access"; - case IFSL_BUFFER_TOO_SMALL: - return "buffer too small"; - case IFSL_SHARING_VIOLATION: - return "sharing violation"; - case IFSL_BAD_INPUT: - return "bad input"; - case IFSL_GENERIC_FAILURE: - return "generic failure"; - case IFSL_OPEN_CREATED: - return "open created"; - case IFSL_OPEN_EXISTS: - return "open exists"; - case IFSL_OPEN_OPENED: - return "opened"; - case IFSL_OPEN_OVERWRITTEN: - return "overwritten"; - case IFSL_OPEN_SUPERSCEDED: - return "supersceded"; - case IFSL_BADFILENAME: - return "bad filename"; - case IFSL_READONLY: - return "read only"; - case IFSL_IS_A_DIR: - return "is a dir"; - case IFSL_PATH_DOES_NOT_EXIST: - return "path does not exist"; - case IFSL_IS_A_FILE: - return "is a file"; - case IFSL_NOT_EMPTY: - return "dir not empty"; - case IFSL_UNSPEC: - return "unspecified error"; - default: - return "NOT FOUND"; - } -} + switch (ifsl) + { + case IFSL_SUCCESS: + return "success"; + case IFSL_DOES_NOT_EXIST: + return "does not exist"; + case IFSL_NOT_IMPLEMENTED: + return "not implemented"; + case IFSL_END_OF_ENUM: + return "end of enum"; + case IFSL_CANNOT_MAKE: + return "cannot make"; + case IFSL_END_OF_FILE: + return "end of file"; + case IFSL_NO_ACCESS: + return "no access"; + case IFSL_BUFFER_TOO_SMALL: + return "buffer too small"; + case IFSL_SHARING_VIOLATION: + return "sharing violation"; + case IFSL_BAD_INPUT: + return "bad input"; + case IFSL_GENERIC_FAILURE: + return "generic failure"; + case IFSL_OPEN_CREATED: + return "open created"; + case IFSL_OPEN_EXISTS: + return "open exists"; + case IFSL_OPEN_OPENED: + return "opened"; + case IFSL_OPEN_OVERWRITTEN: + return "overwritten"; + case IFSL_OPEN_SUPERSCEDED: + return "supersceded"; + case IFSL_BADFILENAME: + return "bad filename"; + case IFSL_READONLY: + return "read only"; + case IFSL_IS_A_DIR: + return "is a dir"; + case IFSL_PATH_DOES_NOT_EXIST: + return "path does not exist"; + case IFSL_IS_A_FILE: + return "is a file"; + case IFSL_NOT_EMPTY: + return "dir not empty"; + case IFSL_UNSPEC: + return "unspecified error"; + default: + return "NOT FOUND"; + } +} unsigned long ifs_MapCmError(unsigned long code) { -switch (code) - { - case CM_ERROR_STOPNOW: - case 0: - return IFSL_SUCCESS; - case CM_ERROR_NOSUCHCELL: - case CM_ERROR_NOSUCHVOLUME: - case CM_ERROR_NOSUCHFILE: // x - return IFSL_DOES_NOT_EXIST; - case CM_ERROR_NOSUCHPATH: // x - return IFSL_PATH_DOES_NOT_EXIST; - case CM_ERROR_BADNTFILENAME: - return IFSL_BADFILENAME; - case CM_ERROR_TIMEDOUT: - case CM_ERROR_ALLOFFLINE: - case CM_ERROR_CLOCKSKEW: - case CM_ERROR_REMOTECONN: - case CM_ERROR_ALLBUSY: - return IFSL_GENERIC_FAILURE; - case CM_ERROR_NOACCESS: - return IFSL_NO_ACCESS; - case CM_ERROR_RETRY: - case CM_ERROR_TOOBIG: - case CM_ERROR_BADFD: - case CM_ERROR_BADFDOP: - case CM_ERROR_CROSSDEVLINK: - return IFSL_GENERIC_FAILURE; - case CM_ERROR_EXISTS: - return IFSL_OPEN_EXISTS; - case CM_ERROR_BADOP: - case CM_ERROR_INVAL: + switch (code) + { + case CM_ERROR_STOPNOW: + case 0: + return IFSL_SUCCESS; + case CM_ERROR_NOSUCHCELL: + case CM_ERROR_NOSUCHVOLUME: + case CM_ERROR_NOSUCHFILE: // x + return IFSL_DOES_NOT_EXIST; + case CM_ERROR_NOSUCHPATH: // x + return IFSL_PATH_DOES_NOT_EXIST; + case CM_ERROR_BADNTFILENAME: + return IFSL_BADFILENAME; + case CM_ERROR_TIMEDOUT: + case CM_ERROR_ALLOFFLINE: + case CM_ERROR_CLOCKSKEW: + case CM_ERROR_REMOTECONN: + case CM_ERROR_ALLBUSY: + return IFSL_GENERIC_FAILURE; + case CM_ERROR_NOACCESS: + return IFSL_NO_ACCESS; + case CM_ERROR_RETRY: + case CM_ERROR_TOOBIG: + case CM_ERROR_BADFD: + case CM_ERROR_BADFDOP: + case CM_ERROR_CROSSDEVLINK: + return IFSL_GENERIC_FAILURE; + case CM_ERROR_EXISTS: + return IFSL_OPEN_EXISTS; + case CM_ERROR_BADOP: + case CM_ERROR_INVAL: case CM_ERROR_UNKNOWN: - case CM_ERROR_BADSMB: - return IFSL_GENERIC_FAILURE;//TODO:? ERR - STATUS_NO_MORE_FILES; - case CM_ERROR_NOTDIR: - case CM_ERROR_ISDIR: - case CM_ERROR_READONLY: - return IFSL_BAD_INPUT; - case CM_ERROR_BUFFERTOOSMALL: - return IFSL_BUFFER_TOO_SMALL; - case CM_ERROR_WOULDBLOCK: - case CM_ERROR_BADSHARENAME: - case CM_ERROR_NOMORETOKENS: - case CM_ERROR_NOTEMPTY: - case CM_ERROR_USESTD: - case CM_ERROR_ATSYS: - return IFSL_GENERIC_FAILURE; - case CM_ERROR_NOFILES: - case CM_ERROR_BADTID: - return IFSL_END_OF_ENUM; - case CM_ERROR_PARTIALWRITE: - case CM_ERROR_NOIPC: - case CM_ERROR_RENAME_IDENTICAL: - case CM_ERROR_AMBIGUOUS_FILENAME: - return IFSL_GENERIC_FAILURE; - case IFSL_SHARING_VIOLATION: - return IFSL_SHARING_VIOLATION; - case IFSL_NOT_EMPTY: - return IFSL_NOT_EMPTY; - case CM_ERROR_SPACE: - case CM_ERROR_QUOTA: - return IFSL_OVERQUOTA; - } -return IFSL_GENERIC_FAILURE; + case CM_ERROR_BADSMB: + return IFSL_GENERIC_FAILURE;//TODO:? ERR - STATUS_NO_MORE_FILES; + case CM_ERROR_NOTDIR: + case CM_ERROR_ISDIR: + case CM_ERROR_READONLY: + return IFSL_BAD_INPUT; + case CM_ERROR_BUFFERTOOSMALL: + return IFSL_BUFFER_TOO_SMALL; + case CM_ERROR_WOULDBLOCK: + case CM_ERROR_BADSHARENAME: + case CM_ERROR_NOMORETOKENS: + case CM_ERROR_NOTEMPTY: + case CM_ERROR_USESTD: + case CM_ERROR_ATSYS: + return IFSL_GENERIC_FAILURE; + case CM_ERROR_NOFILES: + case CM_ERROR_BADTID: + return IFSL_END_OF_ENUM; + case CM_ERROR_PARTIALWRITE: + case CM_ERROR_NOIPC: + case CM_ERROR_RENAME_IDENTICAL: + case CM_ERROR_AMBIGUOUS_FILENAME: + return IFSL_GENERIC_FAILURE; + case IFSL_SHARING_VIOLATION: + return IFSL_SHARING_VIOLATION; + case IFSL_NOT_EMPTY: + return IFSL_NOT_EMPTY; + case CM_ERROR_SPACE: + case CM_ERROR_QUOTA: + return IFSL_OVERQUOTA; + } + return IFSL_GENERIC_FAILURE; } @@ -220,78 +219,78 @@ return IFSL_GENERIC_FAILURE; /****************************/ cm_scache_t *ifs_FindScp(ULONG fid) /* walk list to find scp<->fid mapping */ { -scp_status_t *curr; + scp_status_t *curr; -SCPL_LOCK; + SCPL_LOCK; -curr = scp_list_head; -while (curr) - { + curr = scp_list_head; + while (curr) + { if (curr->fid == fid) - { - SCPL_UNLOCK; - return curr->scp; - } + { + SCPL_UNLOCK; + return curr->scp; + } curr = curr->next; - } -SCPL_UNLOCK; -return NULL; + } + SCPL_UNLOCK; + return NULL; } /* must call with scp write-locked. will always return correct results unless network fails (it loops properly). */ ifs_CheckAcl(cm_scache_t *scp, ULONG access, ULONG *granted) { -long outRights, code; -cm_req_t req; + long outRights, code; + cm_req_t req; -cm_InitReq(&req); + cm_InitReq(&req); -/* ripped from cm_scache.c */ -while (1) - { + /* ripped from cm_scache.c */ + while (1) + { if (cm_HaveAccessRights(scp, userp, access, granted)) - { - return 0; - } + { + return 0; + } else - { - /* we don't know the required access rights */ - code = cm_GetAccessRights(scp, userp, &req); - MAP_RETURN(code); - continue; - } - } - -return 0; + { + /* we don't know the required access rights */ + code = cm_GetAccessRights(scp, userp, &req); + MAP_RETURN(code); + continue; + } + } + + return 0; } /* extract data from scp. in ifs_ support function to centralize changes. */ ifs_CopyInfo(cm_scache_t *scp, ULONG *attribs, LARGE_INTEGER *size, - LARGE_INTEGER *creation, LARGE_INTEGER *access, - LARGE_INTEGER *change, LARGE_INTEGER *written) + LARGE_INTEGER *creation, LARGE_INTEGER *access, + LARGE_INTEGER *change, LARGE_INTEGER *written) { -access->QuadPart = 0; /* these mappings are not quite correct. we have the */ -change->QuadPart = scp->clientModTime; /* right to leave them zero, if necessary. */ -written->QuadPart = scp->clientModTime; -creation->QuadPart = scp->serverModTime; - -*attribs = 0; -if (scp->fileType == CM_SCACHETYPE_DIRECTORY || - scp->fileType == CM_SCACHETYPE_SYMLINK || + access->QuadPart = 0; /* these mappings are not quite correct. we have the */ + change->QuadPart = scp->clientModTime; /* right to leave them zero, if necessary. */ + written->QuadPart = scp->clientModTime; + creation->QuadPart = scp->serverModTime; + + *attribs = 0; + if (scp->fileType == CM_SCACHETYPE_DIRECTORY || + scp->fileType == CM_SCACHETYPE_SYMLINK || scp->fileType == CM_SCACHETYPE_MOUNTPOINT/* || scp->fileType == 0*/) *attribs |= FILE_ATTRIBUTE_DIRECTORY; -/*if (!attribs && scp->fileType == CM_SCACHETYPE_FILE) - *attribs |= FILE_ATTRIBUTE_NORMAL;*/ + /*if (!attribs && scp->fileType == CM_SCACHETYPE_FILE) + *attribs |= FILE_ATTRIBUTE_NORMAL;*/ -if (*attribs == FILE_ATTRIBUTE_DIRECTORY) + if (*attribs == FILE_ATTRIBUTE_DIRECTORY) size->QuadPart = 0; -else + else *size = scp->length; -return 0; + return 0; } @@ -299,13 +298,13 @@ return 0; help eliminate accessing discarded cache entries. */ void ifs_InternalClose(cm_scache_t **scp) { -osi_assert(scp && *scp); -lock_ObtainMutex(&((*scp)->mx)); -cm_ReleaseSCache(*scp); -if ((*scp)->refCount == 0) /* we haven't held scache for external use yet */ + osi_assert(scp && *scp); + lock_ObtainMutex(&((*scp)->mx)); + cm_ReleaseSCache(*scp); + if ((*scp)->refCount == 0) /* we haven't held scache for external use yet */ cm_DiscardSCache(*scp); -lock_ReleaseMutex(&((*scp)->mx)); -*scp = NULL; + lock_ReleaseMutex(&((*scp)->mx)); + *scp = NULL; } /* normalizes path by removing trailing slashes. separates last @@ -313,89 +312,89 @@ lock_ReleaseMutex(&((*scp)->mx)); and *filep points to filename. modifies string path. */ BOOLEAN ifs_FindComponents(char *path, const char **dirp, const char **filep) { -char *lastSep; -BOOLEAN removed; -static char emptyPath[] = "\\"; /* if the path contains only one component, this is the parent. */ + char *lastSep; + BOOLEAN removed; + static char emptyPath[] = "\\"; /* if the path contains only one component, this is the parent. */ -osi_assert(path); + osi_assert(path); -if (strlen(path)) + if (strlen(path)) removed = (path[strlen(path)-1] == '\\'); -else + else removed = 1; -lastSep = strrchr(path, '\\'); -while (lastSep == path + strlen(path) - 1) - { + lastSep = strrchr(path, '\\'); + while (lastSep == path + strlen(path) - 1) + { *lastSep = '\0'; lastSep = strrchr(path, '\\'); - } + } -if (lastSep) - { + if (lastSep) + { *lastSep = '\0'; *dirp = path; *filep = lastSep + 1; - } -else - { + } + else + { lastSep = path + strlen(path); *dirp = emptyPath; *filep = path; - } + } -return removed; + return removed; } /* here to make maintenance easy */ unsigned long ifs_ConvertFileName(wchar_t *in, unsigned int inchars, char *out, unsigned int outchars) { -unsigned long code; + unsigned long code; -code = WideCharToMultiByte(CP_UTF8, 0/*WC_NO_BEST_FIT_CHARS*/, in, inchars, out, outchars-1, NULL, NULL); -if (!code) + code = WideCharToMultiByte(CP_UTF8, 0/*WC_NO_BEST_FIT_CHARS*/, in, inchars, out, outchars-1, NULL, NULL); + if (!code) return IFSL_BADFILENAME; -return 0; + return 0; } /* called by rpc_ library to let us initialize environment. call with id of zero to clear current thread auth. */ ifs_ImpersonateClient(LARGE_INTEGER user_id) { -int x, empty; + int x, empty; -if (!user_id.QuadPart) - { + if (!user_id.QuadPart) + { userp = NULL; return 0; - } + } -empty = -1; -EnterCriticalSection(&mapLock); -for (x = 0; x < MAX_USERS; x++) - { + empty = -1; + EnterCriticalSection(&mapLock); + for (x = 0; x < MAX_USERS; x++) + { if (user_map[x].id.QuadPart == 0) - empty = x; - if (user_map[x].id.QuadPart == user_id.QuadPart) - goto done; - } -if (empty == -1) - { + empty = x; + if (user_map[x].id.QuadPart == user_id.QuadPart) + goto done; + } + if (empty == -1) + { LeaveCriticalSection(&mapLock); return -1; - } -user_map[empty].id = user_id; -user_map[empty].creds = cm_NewUser(); -x = empty; + } + user_map[empty].id = user_id; + user_map[empty].creds = cm_NewUser(); + x = empty; -done: - userp = user_map[x].creds; -LeaveCriticalSection(&mapLock); + done: + userp = user_map[x].creds; + LeaveCriticalSection(&mapLock); -return 0; + return 0; } @@ -404,56 +403,56 @@ return 0; /****************************/ uc_namei(WCHAR *name, ULONG *fid) /* performs name<->fid mapping, and enters it into table */ { -char *buffer; /* we support semi-infinite path lengths */ -long code; -cm_scache_t *scp, *dscp; -char *dirp, *filep; -cm_req_t req; -scp_status_t *st; -short len; - -cm_InitReq(&req); - -len = wcslen(name)+20; /* characters *should* map 1<->1, but in case */ -buffer = malloc(len); -code = ifs_ConvertFileName(name, -1, buffer, len); -if (code) - { + char *buffer; /* we support semi-infinite path lengths */ + long code; + cm_scache_t *scp, *dscp; + char *dirp, *filep; + cm_req_t req; + scp_status_t *st; + short len; + + cm_InitReq(&req); + + len = wcslen(name)+20; /* characters *should* map 1<->1, but in case */ + buffer = malloc(len); + code = ifs_ConvertFileName(name, -1, buffer, len); + if (code) + { free(buffer); MAP_RETURN(code); - } -ifs_FindComponents(buffer, &dirp, &filep); + } + ifs_FindComponents(buffer, &dirp, &filep); -code = cm_NameI(cm_data.rootSCachep, dirp, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW | CM_FLAG_CHECKPATH, userp, ROOTPATH, &req, &dscp); -if (code) - { + code = cm_NameI(cm_data.rootSCachep, dirp, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW | CM_FLAG_CHECKPATH, userp, ROOTPATH, &req, &dscp); + if (code) + { free(buffer); MAP_RETURN(code); - } -if (*filep) + } + if (*filep) code = cm_Lookup(dscp, filep, 0, userp, &req, &scp); -else + else cm_HoldSCache(scp = dscp); -cm_ReleaseSCache(dscp); + cm_ReleaseSCache(dscp); -if (code) - { + if (code) + { free(buffer); MAP_RETURN(code); - } + } -SCPL_LOCK; -st = malloc(sizeof(scp_status_t)); -st->scp = scp; -st->fid = BUF_FILEHASH(&scp->fid); -st->next = scp_list_head; -scp_list_head = st; -SCPL_UNLOCK; + SCPL_LOCK; + st = malloc(sizeof(scp_status_t)); + st->scp = scp; + st->fid = BUF_FILEHASH(&scp->fid); + st->next = scp_list_head; + scp_list_head = st; + SCPL_UNLOCK; -*fid = st->fid; -free(buffer); + *fid = st->fid; + free(buffer); -return 0; + return 0; } /* this should only be called right after open, so we do not need to stat file. @@ -461,142 +460,142 @@ return 0; * kernel. the access mode we grant sticks with the file_object until its death. */ uc_check_access(ULONG fid, ULONG access, ULONG *granted) { -ULONG afs_acc, afs_gr; -cm_scache_t *scp; -ULONG gr; -BOOLEAN file, dir; - -gr = 0; - -scp = ifs_FindScp(fid); -if (!scp) + ULONG afs_acc, afs_gr; + cm_scache_t *scp; + ULONG gr; + BOOLEAN file, dir; + + gr = 0; + + scp = ifs_FindScp(fid); + if (!scp) return IFSL_BAD_INPUT; -file = (scp->fileType == CM_SCACHETYPE_FILE); -dir = !file; + file = (scp->fileType == CM_SCACHETYPE_FILE); + dir = !file; -/* access definitions from prs_fs.h */ -afs_acc = 0; -if (access & FILE_READ_DATA) + /* access definitions from prs_fs.h */ + afs_acc = 0; + if (access & FILE_READ_DATA) afs_acc |= PRSFS_READ; -if (file && ((access & FILE_WRITE_DATA) || (access & FILE_APPEND_DATA))) + if (file && ((access & FILE_WRITE_DATA) || (access & FILE_APPEND_DATA))) afs_acc |= PRSFS_WRITE; -if (access & FILE_WRITE_EA || access & FILE_WRITE_ATTRIBUTES) + if (access & FILE_WRITE_EA || access & FILE_WRITE_ATTRIBUTES) afs_acc |= PRSFS_WRITE; -if (dir && ((access & FILE_ADD_FILE) || (access & FILE_ADD_SUBDIRECTORY))) + if (dir && ((access & FILE_ADD_FILE) || (access & FILE_ADD_SUBDIRECTORY))) afs_acc |= PRSFS_INSERT; -if (dir && (access & FILE_LIST_DIRECTORY)) + if (dir && (access & FILE_LIST_DIRECTORY)) afs_acc |= PRSFS_LOOKUP; -if (access & FILE_READ_EA || access & FILE_READ_ATTRIBUTES) + if (access & FILE_READ_EA || access & FILE_READ_ATTRIBUTES) afs_acc |= PRSFS_LOOKUP; -if (file && (access & FILE_EXECUTE)) /* look at making this require write access */ + if (file && (access & FILE_EXECUTE)) /* look at making this require write access */ afs_acc |= PRSFS_WRITE; -if (dir && (access & FILE_TRAVERSE)) + if (dir && (access & FILE_TRAVERSE)) afs_acc |= PRSFS_READ; -if (dir && (access & FILE_DELETE_CHILD)) + if (dir && (access & FILE_DELETE_CHILD)) afs_acc |= PRSFS_DELETE; -if (/*file && */(access & DELETE)) + if (/*file && */(access & DELETE)) afs_acc |= PRSFS_DELETE; -/* check ACL with server */ -lock_ObtainMutex(&(scp->mx)); -ifs_CheckAcl(scp, afs_acc, &afs_gr); -lock_ReleaseMutex(&(scp->mx)); + /* check ACL with server */ + lock_ObtainMutex(&(scp->mx)); + ifs_CheckAcl(scp, afs_acc, &afs_gr); + lock_ReleaseMutex(&(scp->mx)); -*granted = 0; -if (afs_gr & PRSFS_READ) + *granted = 0; + if (afs_gr & PRSFS_READ) *granted |= FILE_READ_DATA | FILE_EXECUTE; -if (afs_gr & PRSFS_WRITE) + if (afs_gr & PRSFS_WRITE) *granted |= FILE_WRITE_DATA | FILE_APPEND_DATA | FILE_WRITE_EA | FILE_WRITE_ATTRIBUTES | FILE_EXECUTE; // last one hack -if (afs_gr & PRSFS_INSERT) + if (afs_gr & PRSFS_INSERT) *granted |= (dir ? FILE_ADD_FILE | FILE_ADD_SUBDIRECTORY : 0) | (file ? FILE_ADD_SUBDIRECTORY : 0); -if (afs_gr & PRSFS_LOOKUP) - *granted |= (dir ? FILE_LIST_DIRECTORY : 0) | FILE_READ_EA | FILE_READ_ATTRIBUTES; -if (afs_gr & PRSFS_DELETE) + if (afs_gr & PRSFS_LOOKUP) + *granted |= (dir ? FILE_LIST_DIRECTORY : 0) | FILE_READ_EA | FILE_READ_ATTRIBUTES; + if (afs_gr & PRSFS_DELETE) *granted |= FILE_DELETE_CHILD | DELETE; -if (afs_gr & PRSFS_LOCK) - *granted |= 0; -if (afs_gr & PRSFS_ADMINISTER) + if (afs_gr & PRSFS_LOCK) + *granted |= 0; + if (afs_gr & PRSFS_ADMINISTER) *granted |= 0; -* granted |= SYNCHRONIZE | READ_CONTROL; + * granted |= SYNCHRONIZE | READ_CONTROL; -return 0; + return 0; } uc_create(WCHAR *name, ULONG attribs, LARGE_INTEGER alloc, ULONG access, ULONG *granted, ULONG *fid) { -char *buffer; /* we support semi-infinite path lengths */ -long code; -cm_scache_t *scp, *dscp; -char *dirp, *filep; -unsigned char removed; -cm_req_t req; -scp_status_t *st; -cm_attr_t attr; -short len; - -cm_InitReq(&req); - -len = wcslen(name)+20; /* characters *should* map 1<->1, but in case */ -buffer = malloc(len); -code = ifs_ConvertFileName(name, -1, buffer, len); -if (code) - { + char *buffer; /* we support semi-infinite path lengths */ + long code; + cm_scache_t *scp, *dscp; + char *dirp, *filep; + unsigned char removed; + cm_req_t req; + scp_status_t *st; + cm_attr_t attr; + short len; + + cm_InitReq(&req); + + len = wcslen(name)+20; /* characters *should* map 1<->1, but in case */ + buffer = malloc(len); + code = ifs_ConvertFileName(name, -1, buffer, len); + if (code) + { free(buffer); MAP_RETURN(code); - } -removed = ifs_FindComponents(buffer, &dirp, &filep); + } + removed = ifs_FindComponents(buffer, &dirp, &filep); -/* lookup the parent directory, which must exist */ -code = cm_NameI(cm_data.rootSCachep, dirp, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW | CM_FLAG_CHECKPATH, userp, ROOTPATH, &req, &dscp); -if (code) - { + /* lookup the parent directory, which must exist */ + code = cm_NameI(cm_data.rootSCachep, dirp, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW | CM_FLAG_CHECKPATH, userp, ROOTPATH, &req, &dscp); + if (code) + { free(buffer); MAP_RETURN(code); - } + } -osi_assert(filep); -if (*filep) - { + osi_assert(filep); + if (*filep) + { attr.mask = CM_ATTRMASK_LENGTH; attr.length = alloc; if (attribs & FILE_ATTRIBUTE_DIRECTORY) - { - code = cm_MakeDir(dscp, filep, 0, &attr, userp, &req); - if (!code) - code = cm_Lookup(dscp, filep, 0, userp, &req, &scp); - } + { + code = cm_MakeDir(dscp, filep, 0, &attr, userp, &req); + if (!code) + code = cm_Lookup(dscp, filep, 0, userp, &req, &scp); + } else - { - /* for debugging strange error */ - /*if (!strcmp(filep+strlen(filep)-3, "478") || - !strcmp(filep+strlen(filep)-3, "503")) - _asm int 3;*/ - code = cm_Create(dscp, filep, 0, &attr, &scp, userp, &req); - } - } -cm_ReleaseSCache(dscp); - -if (code) - { + { + /* for debugging strange error */ + /*if (!strcmp(filep+strlen(filep)-3, "478") || + !strcmp(filep+strlen(filep)-3, "503")) + _asm int 3;*/ + code = cm_Create(dscp, filep, 0, &attr, &scp, userp, &req); + } + } + cm_ReleaseSCache(dscp); + + if (code) + { free(buffer); MAP_RETURN(code); - } + } -SCPL_LOCK; -st = malloc(sizeof(scp_status_t)); -st->scp = scp; -st->fid = BUF_FILEHASH(&scp->fid); -st->next = scp_list_head; -scp_list_head = st; -SCPL_UNLOCK; + SCPL_LOCK; + st = malloc(sizeof(scp_status_t)); + st->scp = scp; + st->fid = BUF_FILEHASH(&scp->fid); + st->next = scp_list_head; + scp_list_head = st; + SCPL_UNLOCK; -*fid = st->fid; -*granted = access; + *fid = st->fid; + *granted = access; -return 0; + return 0; } /* this does not fill the attribs member completely. additional flags must @@ -604,574 +603,574 @@ return 0; uc_stat(ULONG fid, ULONG *attribs, LARGE_INTEGER *size, LARGE_INTEGER *creation, LARGE_INTEGER *access, LARGE_INTEGER *change, LARGE_INTEGER *written) { -cm_scache_t *scp; -cm_req_t req; -ULONG code; + cm_scache_t *scp; + cm_req_t req; + ULONG code; -scp = ifs_FindScp(fid); -if (!scp) + scp = ifs_FindScp(fid); + if (!scp) return IFSL_BAD_INPUT; -/* stat file; don't want callback */ -cm_InitReq(&req); -lock_ObtainMutex(&(scp->mx)); -cm_HoldUser(userp); -code = cm_SyncOp(scp, NULL, userp, &req, 0, CM_SCACHESYNC_GETSTATUS); -cm_ReleaseUser(userp); + /* stat file; don't want callback */ + cm_InitReq(&req); + lock_ObtainMutex(&(scp->mx)); + cm_HoldUser(userp); + code = cm_SyncOp(scp, NULL, userp, &req, 0, CM_SCACHESYNC_GETSTATUS); + cm_ReleaseUser(userp); -if (code) + if (code) lock_ReleaseMutex(&(scp->mx)); -MAP_RETURN(code); + MAP_RETURN(code); -code = ifs_CopyInfo(scp, attribs, size, creation, access, change, written); -lock_ReleaseMutex(&(scp->mx)); -MAP_RETURN(code); + code = ifs_CopyInfo(scp, attribs, size, creation, access, change, written); + lock_ReleaseMutex(&(scp->mx)); + MAP_RETURN(code); -return 0; + return 0; } /* set atime, mtime, etc. */ uc_setinfo(ULONG fid, ULONG attribs, LARGE_INTEGER creation, LARGE_INTEGER access, LARGE_INTEGER change, LARGE_INTEGER written) { -return IFSL_GENERIC_FAILURE; + return IFSL_GENERIC_FAILURE; } //FIX/quota errors /* truncate or extend file, in cache and on server */ uc_trunc(ULONG fid, LARGE_INTEGER size) { -ULONG code, gr; -cm_scache_t *scp; -cm_req_t req; -osi_hyper_t oldLen, writePos; -long written; - -scp = ifs_FindScp(fid); -if (!scp) + ULONG code, gr; + cm_scache_t *scp; + cm_req_t req; + osi_hyper_t oldLen, writePos; + long written; + + scp = ifs_FindScp(fid); + if (!scp) return IFSL_BAD_INPUT; -/*code = ifs_CheckAcl(scp, FILE_WRITE_DATA, &gr); -if (code) - return code; -if (!(gr & FILE_WRITE_DATA)) - return IFSL_NO_ACCESS;*/ + /*code = ifs_CheckAcl(scp, FILE_WRITE_DATA, &gr); + if (code) + return code; + if (!(gr & FILE_WRITE_DATA)) + return IFSL_NO_ACCESS;*/ -cm_InitReq(&req); -lock_ObtainMutex(&(scp->mx)); + cm_InitReq(&req); + lock_ObtainMutex(&(scp->mx)); -code = cm_SyncOp(scp, NULL, userp, &req, 0, CM_SCACHESYNC_GETSTATUS); + code = cm_SyncOp(scp, NULL, userp, &req, 0, CM_SCACHESYNC_GETSTATUS); -if (code) + if (code) lock_ReleaseMutex(&(scp->mx)); -MAP_RETURN(code); + MAP_RETURN(code); -oldLen = scp->length; -lock_ReleaseMutex(&(scp->mx)); + oldLen = scp->length; + lock_ReleaseMutex(&(scp->mx)); -code = cm_SetLength(scp, &size, userp, &req); -MAP_RETURN(code); -/*code = cm_FSync(scp, userp, &req); -MAP_RETURN(code);*/ -/*code = cm_SyncOp(scp, NULL, userp, &req, 0, CM_SCACHESYNC_GETSTATUS); -MAP_RETURN(code);*/ + code = cm_SetLength(scp, &size, userp, &req); + MAP_RETURN(code); + /*code = cm_FSync(scp, userp, &req); + MAP_RETURN(code);*/ + /*code = cm_SyncOp(scp, NULL, userp, &req, 0, CM_SCACHESYNC_GETSTATUS); + MAP_RETURN(code);*/ #if 0 -/* attempt to write last byte of file. fails to help because of delayed writing. */ -if (oldLen.QuadPart < size.QuadPart) - { + /* attempt to write last byte of file. fails to help because of delayed writing. */ + if (oldLen.QuadPart < size.QuadPart) + { writePos.QuadPart = size.QuadPart - 1; WriteData(scp, writePos, 1, &"\0\0\0", userp, &written); MAP_RETURN(code); if (written != 1) - return IFSL_UNSPEC; - } + return IFSL_UNSPEC; + } #endif -/*cm_SyncOp(scp, NULL, -cm_Flush(*/ -//MAP_RETURN(code); + /*cm_SyncOp(scp, NULL, + cm_Flush(*/ + //MAP_RETURN(code); -return 0; + return 0; } /* read data from a file */ uc_read(ULONG fid, LARGE_INTEGER offset, ULONG length, ULONG *read, char *data) { -ULONG code; -cm_scache_t *scp; -cm_req_t req; - -//_asm int 3; + ULONG code; + cm_scache_t *scp; + cm_req_t req; -*read = 0; + //_asm int 3; -scp = ifs_FindScp(fid); -if (!scp) + *read = 0; + + scp = ifs_FindScp(fid); + if (!scp) return IFSL_BAD_INPUT; -if (scp->fileType == CM_SCACHETYPE_DIRECTORY) + if (scp->fileType == CM_SCACHETYPE_DIRECTORY) return IFSL_IS_A_DIR; -code = ReadData(scp, offset, (unsigned long)length, data, userp, read); -MAP_RETURN(code); + code = ReadData(scp, offset, (unsigned long)length, data, userp, read); + MAP_RETURN(code); -return 0; + return 0; } //FIX/ handle quota errors properly /* write data to a file */ uc_write(ULONG fid, LARGE_INTEGER offset, ULONG length, ULONG *written, char *data) { -ULONG code, gr; -cm_scache_t *scp; -cm_req_t req; + ULONG code, gr; + cm_scache_t *scp; + cm_req_t req; -scp = ifs_FindScp(fid); -if (!scp) + scp = ifs_FindScp(fid); + if (!scp) return IFSL_BAD_INPUT; -/*code = ifs_CheckAcl(scp, FILE_WRITE_DATA, &gr); -if (code) - return code; -if (!(gr & FILE_WRITE_DATA)) - return IFSL_NO_ACCESS;*/ + /*code = ifs_CheckAcl(scp, FILE_WRITE_DATA, &gr); + if (code) + return code; + if (!(gr & FILE_WRITE_DATA)) + return IFSL_NO_ACCESS;*/ -if (offset.QuadPart == -1) // perhaps re-stat here? + if (offset.QuadPart == -1) // perhaps re-stat here? offset = scp->length; -code = WriteData(scp, offset, (unsigned long)length, data, userp, written); -MAP_RETURN(code); + code = WriteData(scp, offset, (unsigned long)length, data, userp, written); + MAP_RETURN(code); -return 0; + return 0; } //need downcall for new length uc_rename(ULONG fid, WCHAR *curr, WCHAR *new_dir, WCHAR *new_name, ULONG *new_fid) { -int code; -cm_req_t req; -//struct vnode *node; -cm_attr_t attr; -wchar_t *buf; -char *curdir, *curfile, *newdir, *newfile; -cm_scache_t *dscp1, *dscp2, *scp; -char b1[MAX_PATH], b2[MAX_PATH], b3[MAX_PATH]; -ULONG fid2; - - -code = !(scp = ifs_FindScp(fid)); -if (!code) + int code; + cm_req_t req; + //struct vnode *node; + cm_attr_t attr; + wchar_t *buf; + char *curdir, *curfile, *newdir, *newfile; + cm_scache_t *dscp1, *dscp2, *scp; + char b1[MAX_PATH], b2[MAX_PATH], b3[MAX_PATH]; + ULONG fid2; + + + code = !(scp = ifs_FindScp(fid)); + if (!code) code = ifs_ConvertFileName(curr, -1, b1, MAX_PATH); -if (!code) + if (!code) code = ifs_ConvertFileName(new_name, -1, b2, MAX_PATH); -if (!code) + if (!code) code = ifs_ConvertFileName(new_dir, -1, b3, MAX_PATH); -if (!code) - { + if (!code) + { ifs_FindComponents(b1, &curdir, &curfile); ifs_FindComponents(b2, &newdir, &newfile); newdir = b3; /*lock_ReleaseMutex(&scp->mx); cm_FSync(scp, userp, &req); if (scp->refCount != 1) - _asm int 3; + _asm int 3; ifs_InternalClose(&scp);*/ uc_close(fid); code = cm_NameI(cm_data.rootSCachep, curdir, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW | CM_FLAG_CHECKPATH, userp, ROOTPATH, &req, &dscp1); - } -if (!code) - { + } + if (!code) + { if (!strcmp(curdir, newdir)) - { - dscp2 = dscp1; - dscp1->refCount++; - } + { + dscp2 = dscp1; + dscp1->refCount++; + } else - code = cm_NameI(cm_data.rootSCachep, newdir, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW | CM_FLAG_CHECKPATH, userp, ROOTPATH, &req, &dscp2); + code = cm_NameI(cm_data.rootSCachep, newdir, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW | CM_FLAG_CHECKPATH, userp, ROOTPATH, &req, &dscp2); if (!code) - { - code = cm_Rename(dscp1, curfile, dscp2, newfile, userp, &req); - //ifs_InternalClose(&dscp2); - //cm_InitReq(&req); - //code = cm_NameI(cm_rootSCachep, newdir, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW | CM_FLAG_CHECKPATH, userp, ROOTPATH, &req, &dscp2); - if (!code) - { - code = ifs_ConvertFileName(curr, -1, b1, MAX_PATH); - code = uc_namei(b1, new_fid); - //if (fid != fid2) - // _asm int 3; - //code = cm_Lookup(dscp2, newfile, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, userp, &req, &node->scp); - } - ifs_InternalClose(&dscp2); - } + { + code = cm_Rename(dscp1, curfile, dscp2, newfile, userp, &req); + //ifs_InternalClose(&dscp2); + //cm_InitReq(&req); + //code = cm_NameI(cm_rootSCachep, newdir, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW | CM_FLAG_CHECKPATH, userp, ROOTPATH, &req, &dscp2); + if (!code) + { + code = ifs_ConvertFileName(curr, -1, b1, MAX_PATH); + code = uc_namei(b1, new_fid); + //if (fid != fid2) + // _asm int 3; + //code = cm_Lookup(dscp2, newfile, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, userp, &req, &node->scp); + } + ifs_InternalClose(&dscp2); + } else - { - //code = cm_Lookup(dscp1, curfile, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, userp, &req, &node->scp); - code = ifs_ConvertFileName(curr, -1, b1, MAX_PATH); - code = uc_namei(b1, new_fid); - //if (fid != fid2) - // _asm int 3; - } + { + //code = cm_Lookup(dscp1, curfile, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, userp, &req, &node->scp); + code = ifs_ConvertFileName(curr, -1, b1, MAX_PATH); + code = uc_namei(b1, new_fid); + //if (fid != fid2) + // _asm int 3; + } ifs_InternalClose(&dscp1); - } + } -return 0; + return 0; } ifs_ReaddirCallback(cm_scache_t *scp, cm_dirEntry_t *entry, void *param, osi_hyper_t *offset) { -readdir_context_t *context; -ULONG name_len, gr; -readdir_data_t *info; -char short_name[14], *endp; -ULONG code; -cm_req_t req; -cm_scache_t *child_scp; -cm_fid_t child_fid; -int t; - -context = param; - -name_len = strlen(entry->name); - -info = (readdir_data_t *)context->buf_pos; -if (context->length - (context->buf_pos - context->buf) < sizeof(readdir_data_t) + name_len * sizeof(WCHAR) + sizeof(LARGE_INTEGER)) - { + readdir_context_t *context; + ULONG name_len, gr; + readdir_data_t *info; + char short_name[14], *endp; + ULONG code; + cm_req_t req; + cm_scache_t *child_scp; + cm_fid_t child_fid; + int t; + + context = param; + + name_len = strlen(entry->name); + + info = (readdir_data_t *)context->buf_pos; + if (context->length - (context->buf_pos - context->buf) < sizeof(readdir_data_t) + name_len * sizeof(WCHAR) + sizeof(LARGE_INTEGER)) + { if (context->count == 0) - return CM_ERROR_BUFFERTOOSMALL; + return CM_ERROR_BUFFERTOOSMALL; info->cookie = *offset; return CM_ERROR_STOPNOW; - } + } -if ((context->matchString && context->matchString[0] && (!strcmp(context->matchString, entry->name) || context->matchString[0]=='*')) || - !(context->matchString && context->matchString[0])) - ; -else + if ((context->matchString && context->matchString[0] && (!strcmp(context->matchString, entry->name) || context->matchString[0]=='*')) || + !(context->matchString && context->matchString[0])) + ; + else return 0; -cm_InitReq(&req); -cm_HoldUser(userp); -child_scp = NULL; - -child_fid.cell = scp->fid.cell; -child_fid.volume = scp->fid.volume; -child_fid.vnode = ntohl(entry->fid.vnode); -child_fid.unique = ntohl(entry->fid.unique); -code = cm_GetSCache(&child_fid, &child_scp, userp, &req); -//code = cm_Lookup(scp, entry->name, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, userp, &req, &child_scp); -if (code || !child_scp) - { + cm_InitReq(&req); + cm_HoldUser(userp); + child_scp = NULL; + + child_fid.cell = scp->fid.cell; + child_fid.volume = scp->fid.volume; + child_fid.vnode = ntohl(entry->fid.vnode); + child_fid.unique = ntohl(entry->fid.unique); + code = cm_GetSCache(&child_fid, &child_scp, userp, &req); + //code = cm_Lookup(scp, entry->name, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, userp, &req, &child_scp); + if (code || !child_scp) + { cm_ReleaseUser(userp); return 0; - } + } -//if (child_scp->refCount == 1) - { + //if (child_scp->refCount == 1) + { lock_ObtainMutex(&child_scp->mx); code = cm_SyncOp(child_scp, NULL, userp, &req, 0, CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_NEEDCALLBACK); // do not need callback lock_ReleaseMutex(&child_scp->mx); - } + } -if (code) /* perhaps blank fields we do not know, and continue. bad filents should not prevent readdirs. */ + if (code) /* perhaps blank fields we do not know, and continue. bad filents should not prevent readdirs. */ ; -info->cookie = *offset; + info->cookie = *offset; -lock_ObtainMutex(&(child_scp->mx)); -code = ifs_CopyInfo(child_scp, &info->attribs, &info->size, &info->creation, &info->access, &info->change, &info->write); -//ifs_CheckAcl(child_scp, FILE_WRITE_DATA, &gr); /* perhaps add flag to not loop, to avoid network traffic if not found*/ -//if (gr & FILE_READ_DATA && !(gr & FILE_WRITE_DATA)) -// info->attribs |= FILE_ATTRIBUTE_READONLY; -lock_ReleaseMutex(&(child_scp->mx)); -ifs_InternalClose(&child_scp); -MAP_RETURN(code); + lock_ObtainMutex(&(child_scp->mx)); + code = ifs_CopyInfo(child_scp, &info->attribs, &info->size, &info->creation, &info->access, &info->change, &info->write); + //ifs_CheckAcl(child_scp, FILE_WRITE_DATA, &gr); /* perhaps add flag to not loop, to avoid network traffic if not found*/ + //if (gr & FILE_READ_DATA && !(gr & FILE_WRITE_DATA)) + // info->attribs |= FILE_ATTRIBUTE_READONLY; + lock_ReleaseMutex(&(child_scp->mx)); + ifs_InternalClose(&child_scp); + MAP_RETURN(code); -cm_Gen8Dot3Name(entry, short_name, &endp); -*endp = '\0'; -info->short_name_length = sizeof(WCHAR)*((t=MultiByteToWideChar(CP_UTF8, 0, short_name, -1, info->short_name, 14))?t-1:0); -info->name_length = sizeof(WCHAR)*((t=MultiByteToWideChar(CP_UTF8, 0, entry->name, -1, info->name, 600))?t-1:0); + cm_Gen8Dot3Name(entry, short_name, &endp); + *endp = '\0'; + info->short_name_length = sizeof(WCHAR)*((t=MultiByteToWideChar(CP_UTF8, 0, short_name, -1, info->short_name, 14))?t-1:0); + info->name_length = sizeof(WCHAR)*((t=MultiByteToWideChar(CP_UTF8, 0, entry->name, -1, info->name, 600))?t-1:0); -context->buf_pos = ((char*)info) + sizeof(readdir_data_t) + info->name_length; -context->count++; + context->buf_pos = ((char*)info) + sizeof(readdir_data_t) + info->name_length; + context->count++; -info = (readdir_data_t *)context->buf_pos; -info->cookie.QuadPart = -1; + info = (readdir_data_t *)context->buf_pos; + info->cookie.QuadPart = -1; -return 0; + return 0; } uc_readdir(ULONG fid, LARGE_INTEGER cookie_in, WCHAR *filter, ULONG *count, char *data, ULONG *len) { -ULONG code; -char buffer[2048]; -cm_req_t req; -cm_scache_t *scp, *child_scp; -readdir_context_t context; -LARGE_INTEGER cookie; - -if (cookie_in.QuadPart == -1) - { + ULONG code; + char buffer[2048]; + cm_req_t req; + cm_scache_t *scp, *child_scp; + readdir_context_t context; + LARGE_INTEGER cookie; + + if (cookie_in.QuadPart == -1) + { *len = 0; *count = 0; return 0; - } + } -scp = ifs_FindScp(fid); -if (!scp) + scp = ifs_FindScp(fid); + if (!scp) return IFSL_BAD_INPUT; -code = ifs_ConvertFileName(filter, -1, buffer, 2048); -if (code) + code = ifs_ConvertFileName(filter, -1, buffer, 2048); + if (code) return code; -cm_InitReq(&req); -cm_HoldUser(userp); + cm_InitReq(&req); + cm_HoldUser(userp); -cookie = cookie_in; -context.matchString = buffer; -context.buf_pos = context.buf = data; -context.length = *len; -context.count = 0; -*count = 0; + cookie = cookie_in; + context.matchString = buffer; + context.buf_pos = context.buf = data; + context.length = *len; + context.count = 0; + *count = 0; -//restart: + //restart: -((LARGE_INTEGER *)context.buf)->QuadPart = -1; + ((LARGE_INTEGER *)context.buf)->QuadPart = -1; -code = cm_ApplyDir(scp, ifs_ReaddirCallback, &context, &cookie, userp, &req, NULL); + code = cm_ApplyDir(scp, ifs_ReaddirCallback, &context, &cookie, userp, &req, NULL); -context.buf_pos += sizeof(LARGE_INTEGER); + context.buf_pos += sizeof(LARGE_INTEGER); -if (code != CM_ERROR_STOPNOW) + if (code != CM_ERROR_STOPNOW) goto done; -//(*count)++; + //(*count)++; -if (code) + if (code) goto done; -//goto restart; + //goto restart; -code = 0; + code = 0; -done: + done: -*count = context.count; + *count = context.count; -cm_ReleaseUser(userp); -*len = context.buf_pos - context.buf; + cm_ReleaseUser(userp); + *len = context.buf_pos - context.buf; -code = ifs_MapCmError(code); -return code; + code = ifs_MapCmError(code); + return code; } uc_close(ULONG fid) { -ULONG code; -cm_scache_t *scp; -cm_req_t req; -scp_status_t *prev, *curr; + ULONG code; + cm_scache_t *scp; + cm_req_t req; + scp_status_t *prev, *curr; -scp = ifs_FindScp(fid); -if (!scp) + scp = ifs_FindScp(fid); + if (!scp) return IFSL_BAD_INPUT; -cm_InitReq(&req); -cm_FSync(scp, userp, &req); + cm_InitReq(&req); + cm_FSync(scp, userp, &req); -SCPL_LOCK; /* perhaps this should be earlier */ + SCPL_LOCK; /* perhaps this should be earlier */ -lock_ObtainMutex(&(scp->mx)); -cm_ReleaseSCache(scp); -if (!scp->refCount) + lock_ObtainMutex(&(scp->mx)); + cm_ReleaseSCache(scp); + if (!scp->refCount) cm_DiscardSCache(scp); -lock_ReleaseMutex(&(scp->mx)); - -prev = NULL, curr = scp_list_head; + lock_ReleaseMutex(&(scp->mx)); + + prev = NULL, curr = scp_list_head; -while (curr) - { + while (curr) + { if (curr->fid == fid) - { - if (prev) - prev->next = curr->next; - else - scp_list_head = curr->next; - free(curr); - break; - } + { + if (prev) + prev->next = curr->next; + else + scp_list_head = curr->next; + free(curr); + break; + } prev = curr; curr = curr->next; - } + } -SCPL_UNLOCK; + SCPL_UNLOCK; -return 0; + return 0; } uc_unlink(WCHAR *name) { -char buffer[2048]; -long code; -cm_scache_t *scp, *dscp; -char *dirp, *filep; -unsigned char removed; -cm_req_t req; -scp_status_t *st; - -cm_InitReq(&req); - -code = ifs_ConvertFileName(name, -1, buffer, 2048); -MAP_RETURN(code); -removed = ifs_FindComponents(buffer, &dirp, &filep); - -code = cm_NameI(cm_data.rootSCachep, dirp, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW | CM_FLAG_CHECKPATH, userp, ROOTPATH, &req, &dscp); -MAP_RETURN(code); -if (*filep) - { + char buffer[2048]; + long code; + cm_scache_t *scp, *dscp; + char *dirp, *filep; + unsigned char removed; + cm_req_t req; + scp_status_t *st; + + cm_InitReq(&req); + + code = ifs_ConvertFileName(name, -1, buffer, 2048); + MAP_RETURN(code); + removed = ifs_FindComponents(buffer, &dirp, &filep); + + code = cm_NameI(cm_data.rootSCachep, dirp, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW | CM_FLAG_CHECKPATH, userp, ROOTPATH, &req, &dscp); + MAP_RETURN(code); + if (*filep) + { code = cm_Unlink(dscp, filep, userp, &req); if (code) - code = cm_RemoveDir(dscp, filep, userp, &req); - } -else + code = cm_RemoveDir(dscp, filep, userp, &req); + } + else ; /* problem */ -cm_ReleaseSCache(dscp); -MAP_RETURN(code); + cm_ReleaseSCache(dscp); + MAP_RETURN(code); -return 0; + return 0; } int uc_ioctl_write(ULONG length, char *data, ULONG *key) { -int code; -cm_req_t req; -smb_ioctl_t *iop; + int code; + cm_req_t req; + smb_ioctl_t *iop; -iop = malloc(sizeof(smb_ioctl_t)); -memset(iop, 0, sizeof(smb_ioctl_t)); -smb_IoctlPrepareWrite(NULL, iop); + iop = malloc(sizeof(smb_ioctl_t)); + memset(iop, 0, sizeof(smb_ioctl_t)); + smb_IoctlPrepareWrite(NULL, iop); -memcpy(iop->inDatap + iop->inCopied, data, length); -iop->inCopied += length; -*key = (ULONG)iop; + memcpy(iop->inDatap + iop->inCopied, data, length); + iop->inCopied += length; + *key = (ULONG)iop; -return 0; + return 0; } int uc_ioctl_read(ULONG key, ULONG *length, char *data) { -int code; -cm_req_t req; -smb_ioctl_t *iop; + int code; + cm_req_t req; + smb_ioctl_t *iop; -iop = key; -osi_assert(iop); + iop = key; + osi_assert(iop); -cm_HoldUser(userp); -smb_IoctlPrepareRead(NULL, iop, userp); -cm_ReleaseUser(userp); + cm_HoldUser(userp); + smb_IoctlPrepareRead(NULL, iop, userp); + cm_ReleaseUser(userp); -*length = iop->outDatap - iop->outAllocp; -memcpy(data, iop->outAllocp, *length); -free(iop); + *length = iop->outDatap - iop->outAllocp; + memcpy(data, iop->outAllocp, *length); + free(iop); -return 0; + return 0; } int ifs_Init(char **reason) { -HANDLE kcom; - -//_asm int 3; -kcom = CreateFile("\\\\.\\afscom\\upcallhook", GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, - /*FILE_FLAG_OVERLAPPED*/0, NULL); -if (kcom == INVALID_HANDLE_VALUE) - { + HANDLE kcom; + + //_asm int 3; + kcom = CreateFile("\\\\.\\afscom\\upcallhook", GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, + /*FILE_FLAG_OVERLAPPED*/0, NULL); + if (kcom == INVALID_HANDLE_VALUE) + { *reason = "error creating communications file"; return CM_ERROR_REMOTECONN; - } -CloseHandle(kcom); + } + CloseHandle(kcom); -memset(user_map, 0, 32*sizeof(struct user_map_entry)); -InitializeCriticalSection(&mapLock); -InitializeCriticalSection(&scp_list_lock); + memset(user_map, 0, 32*sizeof(struct user_map_entry)); + InitializeCriticalSection(&mapLock); + InitializeCriticalSection(&scp_list_lock); -return 0; + return 0; } ifs_TransactRpc(char *outbuf, int outlen, char *inbuf, int *inlen) { -HANDLE hf; -int ret; -DWORD err, read = 0; -DWORD inmax; + HANDLE hf; + int ret; + DWORD err, read = 0; + DWORD inmax; -if (!outbuf || !inbuf) + if (!outbuf || !inbuf) return IFSL_GENERIC_FAILURE; -hf = CreateFile("\\\\.\\afscom\\downcall", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); -if (hf == INVALID_HANDLE_VALUE) + hf = CreateFile("\\\\.\\afscom\\downcall", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); + if (hf == INVALID_HANDLE_VALUE) return 0; -inmax = *inlen; -if (!DeviceIoControl(hf, IOCTL_AFSRDR_DOWNCALL, outbuf, outlen, inbuf, inmax, inlen, NULL)) - { + inmax = *inlen; + if (!DeviceIoControl(hf, IOCTL_AFSRDR_DOWNCALL, outbuf, outlen, inbuf, inmax, inlen, NULL)) + { CloseHandle(hf); return IFSL_GENERIC_FAILURE; - } + } -CloseHandle(hf); -return inlen ? IFSL_SUCCESS : IFSL_GENERIC_FAILURE; + CloseHandle(hf); + return inlen ? IFSL_SUCCESS : IFSL_GENERIC_FAILURE; } DWORD WINAPI ifs_MainLoop(LPVOID param) { -HANDLE pipe; -DWORD written; -unsigned char *bufIn, *bufOut; -DWORD lenIn, lenOut, status; -DWORD err; -OVERLAPPED olp; -rpc_t rpc; -BOOL st; - -bufIn = VirtualAlloc(NULL, TRANSFER_BUF_SIZE, MEM_COMMIT, PAGE_READWRITE); -bufOut = VirtualAlloc(NULL, TRANSFER_BUF_SIZE, MEM_COMMIT, PAGE_READWRITE); -if (!bufIn || !bufOut) - { + HANDLE pipe; + DWORD written; + unsigned char *bufIn, *bufOut; + DWORD lenIn, lenOut, status; + DWORD err; + OVERLAPPED olp; + rpc_t rpc; + BOOL st; + + bufIn = VirtualAlloc(NULL, TRANSFER_BUF_SIZE, MEM_COMMIT, PAGE_READWRITE); + bufOut = VirtualAlloc(NULL, TRANSFER_BUF_SIZE, MEM_COMMIT, PAGE_READWRITE); + if (!bufIn || !bufOut) + { if (bufIn) VirtualFree(bufIn, 0, MEM_RELEASE); if (bufOut) VirtualFree(bufOut, 0, MEM_RELEASE); printf("could not allocate transfer bufs\n"); PostMessage(NULL, WM_CLOSE, 0, 0); return 1; - } - -//_asm int 3; -pipe = CreateFile("\\\\.\\afscom\\upcallhook", GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, - /*FILE_FLAG_OVERLAPPED*/0, NULL); -if (pipe == INVALID_HANDLE_VALUE) - { + } + + //_asm int 3; + pipe = CreateFile("\\\\.\\afscom\\upcallhook", GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, + /*FILE_FLAG_OVERLAPPED*/0, NULL); + if (pipe == INVALID_HANDLE_VALUE) + { VirtualFree(bufIn, 0, MEM_RELEASE); VirtualFree(bufOut, 0, MEM_RELEASE); printf("error creating communications file\n"); PostMessage(NULL, WM_CLOSE, 0, 0); return 1; - } + } -//_asm int 3; -while (1) - { + //_asm int 3; + while (1) + { if (WaitForSingleObject(DoTerminate, 0) == WAIT_OBJECT_0) - break; + break; st = ReadFile(pipe, bufIn, TRANSFER_BUF_SIZE, &lenIn, NULL); if (!st) - if (GetLastError() == ERROR_INVALID_HANDLE) - break; - else - continue; + if (GetLastError() == ERROR_INVALID_HANDLE) + break; + else + continue; ZeroMemory(&rpc, sizeof(rpc)); rpc.in_buf = rpc.in_pos = bufIn; @@ -1181,11 +1180,11 @@ while (1) st = WriteFile(pipe, rpc.out_buf, rpc.out_pos - rpc.out_buf, &written, NULL); if (!st) - if (GetLastError() == ERROR_INVALID_HANDLE) - break; - else - continue; - } + if (GetLastError() == ERROR_INVALID_HANDLE) + break; + else + continue; + } -return 1; + return 1; } diff --git a/src/WINNT/afsd/cm_callback.c b/src/WINNT/afsd/cm_callback.c index 86826e884..3076ed89d 100644 --- a/src/WINNT/afsd/cm_callback.c +++ b/src/WINNT/afsd/cm_callback.c @@ -92,9 +92,9 @@ void cm_RecordRacingRevoke(cm_fid_t *fidp, long cancelFlags) } #ifdef AFSIFS -#define BUF_FILEHASH(fidp) ((((fidp)->vnode+((fidp)->unique << 13) + ((fidp)->unique >> (32-13)) \ - +(fidp)->volume+(fidp)->cell) \ - /*& 0xffffffff*/)) +#define BUF_FILEHASH(fidp) ((((fidp)->vnode+((fidp)->unique << 13) + ((fidp)->unique >> (32-13)) \ + +(fidp)->volume+(fidp)->cell) \ + /*& 0xffffffff*/)) #endif /* @@ -135,7 +135,7 @@ void cm_CallbackNotifyChange(cm_scache_t *scp) FILE_NOTIFY_GENERIC_DIRECTORY_FILTER, scp, NULL, NULL, TRUE); #else - dc_break_callback(BUF_FILEHASH(&scp->fid)); + dc_break_callback(BUF_FILEHASH(&scp->fid)); #endif } else { cm_fid_t tfid; @@ -153,8 +153,8 @@ void cm_CallbackNotifyChange(cm_scache_t *scp) FILE_NOTIFY_GENERIC_FILE_FILTER, dscp, NULL, NULL, TRUE); #else - if (dscp) - dc_break_callback(BUF_FILEHASH(&dscp->fid)); + if (dscp) + dc_break_callback(BUF_FILEHASH(&dscp->fid)); #endif if (dscp) cm_ReleaseSCache(dscp); diff --git a/src/WINNT/afsd/cm_ioctl.c b/src/WINNT/afsd/cm_ioctl.c index bd1cd6368..7a09cb62d 100644 --- a/src/WINNT/afsd/cm_ioctl.c +++ b/src/WINNT/afsd/cm_ioctl.c @@ -159,46 +159,47 @@ long cm_ParseIoctlPath(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp, TranslateExtendedChars(relativePath); #ifdef AFSIFS - /* we have passed the whole path, including the afs prefix (pioctl_nt.c modified) */ - /*_asm int 3; - sprintf(absRoot, "%c:", relativePath[0]); - rootDir = CreateFile(absRoot, 0, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); - - if (!DeviceIoControl(rootDir, IOCTL_AFSRDR_GET_PATH, NULL, 0, absRoot_w, 100*sizeof(wchar_t), &length, NULL)) - { - CloseHandle(rootDir); - return CM_ERROR_NOSUCHPATH; - } - CloseHandle(rootDir); + /* we have passed the whole path, including the afs prefix (pioctl_nt.c modified) */ +#if 0 + /*_asm int 3; */ + sprintf(absRoot, "%c:", relativePath[0]); + rootDir = CreateFile(absRoot, 0, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); - ifs_ConvertFileName(absRoot_w, length/sizeof(wchar_t), absRoot, 100);*/ + if (!DeviceIoControl(rootDir, IOCTL_AFSRDR_GET_PATH, NULL, 0, absRoot_w, 100*sizeof(wchar_t), &length, NULL)) + { + CloseHandle(rootDir); + return CM_ERROR_NOSUCHPATH; + } + CloseHandle(rootDir); + ifs_ConvertFileName(absRoot_w, length/sizeof(wchar_t), absRoot, 100); +#endif #if 0 - switch (relativePath[0]) /* FIXFIX */ - { - case 'y': - case 'Y': - absRoot = "\\ericjw\\test"; /* should use drivemap */ - } + switch (relativePath[0]) /* FIXFIX */ + { + case 'y': + case 'Y': + absRoot = "\\ericjw\\test"; /* should use drivemap */ + } #endif - code = cm_NameI(cm_data.rootSCachep, relativePath, - CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, - userp, ""/*absRoot*//*ioctlp->tidPathp*/, reqp, scpp); + code = cm_NameI(cm_data.rootSCachep, relativePath, + CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, + userp, ""/*absRoot*//*ioctlp->tidPathp*/, reqp, scpp); - if (code) - return code; + if (code) + return code; - /* # of bytes of path */ + /* # of bytes of path */ code = strlen(ioctlp->inDatap) + 1; ioctlp->inDatap += code; /* This is usually nothing, but for StatMountPoint it is the file name. */ TranslateExtendedChars(ioctlp->inDatap); - return 0; -#endif + return 0; +#endif /* AFSIFS */ - if (relativePath[0] == relativePath[1] && + if (relativePath[0] == relativePath[1] && relativePath[1] == '\\' && !_strnicmp(cm_NetbiosName,relativePath+2,strlen(cm_NetbiosName))) { @@ -1832,7 +1833,7 @@ long cm_IoctlSetToken(struct smb_ioctl *ioctlp, struct cm_user *userp) tp += strlen(tp) + 1; #ifndef AFSIFS /* no SMB username */ - if (flags & PIOCTL_LOGON) { + if (flags & PIOCTL_LOGON) { /* SMB user name with which to associate tokens */ smbname = tp; osi_Log2(smb_logp,"cm_IoctlSetToken for user [%s] smbname [%s]", diff --git a/src/WINNT/afsd/cm_vnodeops.c b/src/WINNT/afsd/cm_vnodeops.c index d03179111..61ffcd2a3 100644 --- a/src/WINNT/afsd/cm_vnodeops.c +++ b/src/WINNT/afsd/cm_vnodeops.c @@ -546,19 +546,20 @@ long cm_ApplyDir(cm_scache_t *scp, cm_DirFuncp_t funcp, void *parmp, } #ifdef AFSIFS - lock_ObtainMutex(&scp->mx); - if ((scp->flags & CM_SCACHEFLAG_BULKSTATTING) == 0 - && (scp->bulkStatProgress.QuadPart <= thyper.QuadPart)) - { - scp->flags |= CM_SCACHEFLAG_BULKSTATTING; - cm_TryBulkStat(scp, &thyper, userp, reqp); - scp->flags &= ~CM_SCACHEFLAG_BULKSTATTING; - scp->bulkStatProgress = thyper; - } - lock_ReleaseMutex(&scp->mx); + /* Why was this added for IFS? - jaltman 06/18/2006 */ + lock_ObtainMutex(&scp->mx); + if ((scp->flags & CM_SCACHEFLAG_BULKSTATTING) == 0 + && (scp->bulkStatProgress.QuadPart <= thyper.QuadPart)) + { + scp->flags |= CM_SCACHEFLAG_BULKSTATTING; + cm_TryBulkStat(scp, &thyper, userp, reqp); + scp->flags &= ~CM_SCACHEFLAG_BULKSTATTING; + scp->bulkStatProgress = thyper; + } + lock_ReleaseMutex(&scp->mx); #endif - lock_ObtainMutex(&bufferp->mx); + lock_ObtainMutex(&bufferp->mx); bufferOffset = thyper; /* now get the data in the cache */ diff --git a/src/WINNT/afsd/rawops.c b/src/WINNT/afsd/rawops.c index 928f243d5..4132f4d72 100644 --- a/src/WINNT/afsd/rawops.c +++ b/src/WINNT/afsd/rawops.c @@ -16,349 +16,356 @@ long buf_bufferSize = CM_BUF_SIZE; long ReadData(cm_scache_t *scp, osi_hyper_t offset, long count, char *op, - cm_user_t *userp, long *readp) + cm_user_t *userp, long *readp) { - //osi_hyper_t offset; - long code; - cm_buf_t *bufferp; - osi_hyper_t fileLength; - osi_hyper_t thyper; - osi_hyper_t lastByte; - osi_hyper_t bufferOffset; - long bufIndex, nbytes; - int sequential = 0; - cm_req_t req; - - cm_InitReq(&req); - - bufferp = NULL; - - lock_ObtainMutex(&scp->mx); - - /* start by looking up the file's end */ - code = cm_SyncOp(scp, NULL, userp, &req, 0, - CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); - if (code) goto done; - - /* now we have the entry locked, look up the length */ - fileLength = scp->length; - - /* adjust count down so that it won't go past EOF */ - thyper.LowPart = count; - thyper.HighPart = 0; - thyper = LargeIntegerAdd(offset, thyper); /* where read should end */ - lastByte = thyper; - if (LargeIntegerGreaterThan(thyper, fileLength)) { - /* we'd read past EOF, so just stop at fileLength bytes. - * Start by computing how many bytes remain in the file. - */ - thyper = LargeIntegerSubtract(fileLength, offset); - - /* if we are past EOF, read 0 bytes */ - if (LargeIntegerLessThanZero(thyper)) - count = 0; - else - count = thyper.LowPart; - } - - *readp = count; - - /* now, copy the data one buffer at a time, - * until we've filled the request packet - */ - while (1) { - /* if we've copied all the data requested, we're done */ - if (count <= 0) break; - - /* otherwise, load up a buffer of data */ - thyper.HighPart = offset.HighPart; - thyper.LowPart = offset.LowPart & ~(buf_bufferSize-1); - if (!bufferp || !LargeIntegerEqualTo(thyper, bufferOffset)) { - /* wrong buffer */ - if (bufferp) { - buf_Release(bufferp); - bufferp = NULL; - } - lock_ReleaseMutex(&scp->mx); - - lock_ObtainRead(&scp->bufCreateLock); - code = buf_Get(scp, &thyper, &bufferp); - lock_ReleaseRead(&scp->bufCreateLock); - - lock_ObtainMutex(&scp->mx); - if (code) goto done; - bufferOffset = thyper; - - /* now get the data in the cache */ - while (1) { - code = cm_SyncOp(scp, bufferp, userp, &req, 0, - CM_SCACHESYNC_NEEDCALLBACK - | CM_SCACHESYNC_READ); - if (code) goto done; - - if (cm_HaveBuffer(scp, bufferp, 0)) break; - - /* otherwise, load the buffer and try again */ - code = cm_GetBuffer(scp, bufferp, NULL, userp, &req); - if (code) break; - } - if (code) { - buf_Release(bufferp); - bufferp = NULL; - goto done; - } - } /* if (wrong buffer) ... */ - - /* now we have the right buffer loaded. Copy out the - * data from here to the user's buffer. - */ - bufIndex = offset.LowPart & (buf_bufferSize - 1); - - /* and figure out how many bytes we want from this buffer */ - nbytes = buf_bufferSize - bufIndex; /* what remains in buffer */ - if (nbytes > count) nbytes = count; /* don't go past EOF */ - - /* now copy the data */ - memcpy(op, bufferp->datap + bufIndex, nbytes); - - /* adjust counters, pointers, etc. */ - op += nbytes; - count -= nbytes; - thyper.LowPart = nbytes; - thyper.HighPart = 0; - offset = LargeIntegerAdd(thyper, offset); - } /* while 1 */ - -done: - lock_ReleaseMutex(&scp->mx); - //lock_ReleaseMutex(&fidp->mx); - if (bufferp) buf_Release(bufferp); - - if (code == 0 && sequential) - cm_ConsiderPrefetch(scp, &lastByte, userp, &req); - - return code; -} + //osi_hyper_t offset; + long code; + cm_buf_t *bufferp; + osi_hyper_t fileLength; + osi_hyper_t thyper; + osi_hyper_t lastByte; + osi_hyper_t bufferOffset; + long bufIndex, nbytes; + int sequential = 0; + cm_req_t req; + + cm_InitReq(&req); + + bufferp = NULL; + + lock_ObtainMutex(&scp->mx); + + /* start by looking up the file's end */ + code = cm_SyncOp(scp, NULL, userp, &req, 0, + CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); + if (code) + goto done; + + /* now we have the entry locked, look up the length */ + fileLength = scp->length; + + /* adjust count down so that it won't go past EOF */ + thyper.LowPart = count; + thyper.HighPart = 0; + thyper = LargeIntegerAdd(offset, thyper); /* where read should end */ + lastByte = thyper; + if (LargeIntegerGreaterThan(thyper, fileLength)) { + /* we'd read past EOF, so just stop at fileLength bytes. + * Start by computing how many bytes remain in the file. + */ + thyper = LargeIntegerSubtract(fileLength, offset); + + /* if we are past EOF, read 0 bytes */ + if (LargeIntegerLessThanZero(thyper)) + count = 0; + else + count = thyper.LowPart; + } + + *readp = count; + + /* now, copy the data one buffer at a time, + * until we've filled the request packet + */ + while (1) { + /* if we've copied all the data requested, we're done */ + if (count <= 0) break; + + /* otherwise, load up a buffer of data */ + thyper.HighPart = offset.HighPart; + thyper.LowPart = offset.LowPart & ~(buf_bufferSize-1); + if (!bufferp || !LargeIntegerEqualTo(thyper, bufferOffset)) { + /* wrong buffer */ + if (bufferp) { + buf_Release(bufferp); + bufferp = NULL; + } + lock_ReleaseMutex(&scp->mx); + + lock_ObtainRead(&scp->bufCreateLock); + code = buf_Get(scp, &thyper, &bufferp); + lock_ReleaseRead(&scp->bufCreateLock); + + lock_ObtainMutex(&scp->mx); + if (code) goto done; + bufferOffset = thyper; + + /* now get the data in the cache */ + while (1) { + code = cm_SyncOp(scp, bufferp, userp, &req, 0, + CM_SCACHESYNC_NEEDCALLBACK + | CM_SCACHESYNC_READ); + if (code) + goto done; + + if (cm_HaveBuffer(scp, bufferp, 0)) break; + + /* otherwise, load the buffer and try again */ + code = cm_GetBuffer(scp, bufferp, NULL, userp, &req); + if (code) break; + } + if (code) { + buf_Release(bufferp); + bufferp = NULL; + goto done; + } + } /* if (wrong buffer) ... */ + + /* now we have the right buffer loaded. Copy out the + * data from here to the user's buffer. + */ + bufIndex = offset.LowPart & (buf_bufferSize - 1); + + /* and figure out how many bytes we want from this buffer */ + nbytes = buf_bufferSize - bufIndex; /* what remains in buffer */ + if (nbytes > count) nbytes = count; /* don't go past EOF */ + + /* now copy the data */ + memcpy(op, bufferp->datap + bufIndex, nbytes); + + /* adjust counters, pointers, etc. */ + op += nbytes; + count -= nbytes; + thyper.LowPart = nbytes; + thyper.HighPart = 0; + offset = LargeIntegerAdd(thyper, offset); + } /* while 1 */ + + done: + lock_ReleaseMutex(&scp->mx); + //lock_ReleaseMutex(&fidp->mx); + if (bufferp) + buf_Release(bufferp); + + if (code == 0 && sequential) + cm_ConsiderPrefetch(scp, &lastByte, userp, &req); + + return code; +} long WriteData(cm_scache_t *scp, osi_hyper_t offset, long count, char *op, - cm_user_t *userp, long *writtenp) + cm_user_t *userp, long *writtenp) { - long code = 0; - long written = 0; - //cm_scache_t *scp; - osi_hyper_t fileLength; /* file's length at start of write */ - osi_hyper_t minLength; /* don't read past this */ - long nbytes; /* # of bytes to transfer this iteration */ - cm_buf_t *bufferp; - osi_hyper_t thyper; /* hyper tmp variable */ - osi_hyper_t bufferOffset; - long bufIndex; /* index in buffer where our data is */ - int doWriteBack; - osi_hyper_t writeBackOffset; /* offset of region to write back when - * I/O is done */ - DWORD filter = 0; - cm_req_t req; - - cm_InitReq(&req); - - bufferp = NULL; - doWriteBack = 0; - - //scp = fidp->scp; - lock_ObtainMutex(&scp->mx); - - /* start by looking up the file's end */ - code = cm_SyncOp(scp, NULL, userp, &req, 0, - CM_SCACHESYNC_NEEDCALLBACK - | CM_SCACHESYNC_SETSTATUS - | CM_SCACHESYNC_GETSTATUS); - if (code) - goto done; - - /* make sure we have a writable FD */ - /*if (!(fidp->flags & SMB_FID_OPENWRITE)) { - code = CM_ERROR_BADFDOP; - goto done; - } */ + long code = 0; + long written = 0; + osi_hyper_t fileLength; /* file's length at start of write */ + osi_hyper_t minLength; /* don't read past this */ + long nbytes; /* # of bytes to transfer this iteration */ + cm_buf_t *bufferp; + osi_hyper_t thyper; /* hyper tmp variable */ + osi_hyper_t bufferOffset; + long bufIndex; /* index in buffer where our data is */ + int doWriteBack; + osi_hyper_t writeBackOffset; /* offset of region to write back when + * I/O is done */ + DWORD filter = 0; + cm_req_t req; + + cm_InitReq(&req); + + bufferp = NULL; + doWriteBack = 0; + + lock_ObtainMutex(&scp->mx); + + /* start by looking up the file's end */ + code = cm_SyncOp(scp, NULL, userp, &req, 0, + CM_SCACHESYNC_NEEDCALLBACK + | CM_SCACHESYNC_SETSTATUS + | CM_SCACHESYNC_GETSTATUS); + if (code) + goto done; + +#if 0 + /* make sure we have a writable FD */ + if (!(fidp->flags & SMB_FID_OPENWRITE)) { + code = CM_ERROR_BADFDOP; + goto done; + } +#endif - /* now we have the entry locked, look up the length */ - fileLength = scp->length; - minLength = fileLength; - if (LargeIntegerGreaterThan(minLength, scp->serverLength)) - minLength = scp->serverLength; - - /* adjust file length if we extend past EOF */ - thyper.LowPart = count; - thyper.HighPart = 0; - thyper = LargeIntegerAdd(offset, thyper); /* where write should end */ - if (LargeIntegerGreaterThan(thyper, fileLength)) { - /* we'd write past EOF, so extend the file */ - scp->mask |= CM_SCACHEMASK_LENGTH; - scp->length = thyper; - filter |= (FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_SIZE); - } else - filter |= FILE_NOTIFY_CHANGE_LAST_WRITE; - - /* now, if the new position (thyper) and the old (offset) are in - * different storeback windows, remember to store back the previous - * storeback window when we're done with the write. - */ - if ((thyper.LowPart & (-cm_chunkSize)) != - (offset.LowPart & (-cm_chunkSize))) { - /* they're different */ - doWriteBack = 1; - writeBackOffset.HighPart = offset.HighPart; - writeBackOffset.LowPart = offset.LowPart & (-cm_chunkSize); - } - - *writtenp = count; - - /* now, copy the data one buffer at a time, until we've filled the - * request packet */ - while (1) { - /* if we've copied all the data requested, we're done */ - if (count <= 0) break; - - /* handle over quota or out of space */ - if (scp->flags & (CM_SCACHEFLAG_OVERQUOTA | CM_SCACHEFLAG_OUTOFSPACE)) { - *writtenp = written; - break; - } - - /* otherwise, load up a buffer of data */ - thyper.HighPart = offset.HighPart; - thyper.LowPart = offset.LowPart & ~(buf_bufferSize-1); - if (!bufferp || !LargeIntegerEqualTo(thyper, bufferOffset)) { - /* wrong buffer */ - if (bufferp) { - lock_ReleaseMutex(&bufferp->mx); - buf_Release(bufferp); - bufferp = NULL; - } - lock_ReleaseMutex(&scp->mx); - - lock_ObtainRead(&scp->bufCreateLock); - code = buf_Get(scp, &thyper, &bufferp); - lock_ReleaseRead(&scp->bufCreateLock); - - lock_ObtainMutex(&bufferp->mx); - lock_ObtainMutex(&scp->mx); - if (code) goto done; - - bufferOffset = thyper; - - /* now get the data in the cache */ - while (1) { - code = cm_SyncOp(scp, bufferp, userp, &req, 0, - CM_SCACHESYNC_NEEDCALLBACK - | CM_SCACHESYNC_WRITE - | CM_SCACHESYNC_BUFLOCKED); - if (code) - goto done; + /* now we have the entry locked, look up the length */ + fileLength = scp->length; + minLength = fileLength; + if (LargeIntegerGreaterThan(minLength, scp->serverLength)) + minLength = scp->serverLength; + + /* adjust file length if we extend past EOF */ + thyper.LowPart = count; + thyper.HighPart = 0; + thyper = LargeIntegerAdd(offset, thyper); /* where write should end */ + if (LargeIntegerGreaterThan(thyper, fileLength)) { + /* we'd write past EOF, so extend the file */ + scp->mask |= CM_SCACHEMASK_LENGTH; + scp->length = thyper; + filter |= (FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_SIZE); + } else + filter |= FILE_NOTIFY_CHANGE_LAST_WRITE; + + /* now, if the new position (thyper) and the old (offset) are in + * different storeback windows, remember to store back the previous + * storeback window when we're done with the write. + */ + if ((thyper.LowPart & (-cm_chunkSize)) != + (offset.LowPart & (-cm_chunkSize))) { + /* they're different */ + doWriteBack = 1; + writeBackOffset.HighPart = offset.HighPart; + writeBackOffset.LowPart = offset.LowPart & (-cm_chunkSize); + } + + *writtenp = count; + + /* now, copy the data one buffer at a time, until we've filled the + * request packet */ + while (1) { + /* if we've copied all the data requested, we're done */ + if (count <= 0) break; + + /* handle over quota or out of space */ + if (scp->flags & (CM_SCACHEFLAG_OVERQUOTA | CM_SCACHEFLAG_OUTOFSPACE)) { + *writtenp = written; + break; + } + + /* otherwise, load up a buffer of data */ + thyper.HighPart = offset.HighPart; + thyper.LowPart = offset.LowPart & ~(buf_bufferSize-1); + if (!bufferp || !LargeIntegerEqualTo(thyper, bufferOffset)) { + /* wrong buffer */ + if (bufferp) { + lock_ReleaseMutex(&bufferp->mx); + buf_Release(bufferp); + bufferp = NULL; + } + lock_ReleaseMutex(&scp->mx); + + lock_ObtainRead(&scp->bufCreateLock); + code = buf_Get(scp, &thyper, &bufferp); + lock_ReleaseRead(&scp->bufCreateLock); + + lock_ObtainMutex(&bufferp->mx); + lock_ObtainMutex(&scp->mx); + if (code) + goto done; + + bufferOffset = thyper; + + /* now get the data in the cache */ + while (1) { + code = cm_SyncOp(scp, bufferp, userp, &req, 0, + CM_SCACHESYNC_NEEDCALLBACK + | CM_SCACHESYNC_WRITE + | CM_SCACHESYNC_BUFLOCKED); + if (code) + goto done; - /* If we're overwriting the entire buffer, or - * if we're writing at or past EOF, mark the - * buffer as current so we don't call - * cm_GetBuffer. This skips the fetch from the - * server in those cases where we're going to - * obliterate all the data in the buffer anyway, - * or in those cases where there is no useful - * data at the server to start with. - * - * Use minLength instead of scp->length, since - * the latter has already been updated by this - * call. - */ - if (LargeIntegerGreaterThanOrEqualTo(bufferp->offset, minLength) || - LargeIntegerEqualTo(offset, bufferp->offset) && - (count >= buf_bufferSize || - LargeIntegerGreaterThanOrEqualTo(LargeIntegerAdd(offset, ConvertLongToLargeInteger(count)), minLength))) { - if (count < buf_bufferSize - && bufferp->dataVersion == -1) - memset(bufferp->datap, 0, - buf_bufferSize); - bufferp->dataVersion = scp->dataVersion; - } - - if (cm_HaveBuffer(scp, bufferp, 1)) break; - - /* otherwise, load the buffer and try again */ - lock_ReleaseMutex(&bufferp->mx); - code = cm_GetBuffer(scp, bufferp, NULL, userp, - &req); - lock_ReleaseMutex(&scp->mx); - lock_ObtainMutex(&bufferp->mx); - lock_ObtainMutex(&scp->mx); - if (code) break; - } - if (code) { - lock_ReleaseMutex(&bufferp->mx); - buf_Release(bufferp); - bufferp = NULL; - goto done; - } - } /* if (wrong buffer) ... */ - - /* now we have the right buffer loaded. Copy out the - * data from here to the user's buffer. - */ - bufIndex = offset.LowPart & (buf_bufferSize - 1); - - /* and figure out how many bytes we want from this buffer */ - nbytes = buf_bufferSize - bufIndex; /* what remains in buffer */ - if (nbytes > count) - nbytes = count; /* don't go past end of request */ - - /* now copy the data */ + /* If we're overwriting the entire buffer, or + * if we're writing at or past EOF, mark the + * buffer as current so we don't call + * cm_GetBuffer. This skips the fetch from the + * server in those cases where we're going to + * obliterate all the data in the buffer anyway, + * or in those cases where there is no useful + * data at the server to start with. + * + * Use minLength instead of scp->length, since + * the latter has already been updated by this + * call. + */ + if (LargeIntegerGreaterThanOrEqualTo(bufferp->offset, minLength) || + LargeIntegerEqualTo(offset, bufferp->offset) && + (count >= buf_bufferSize || + LargeIntegerGreaterThanOrEqualTo(LargeIntegerAdd(offset, ConvertLongToLargeInteger(count)), minLength))) { + if (count < buf_bufferSize + && bufferp->dataVersion == -1) + memset(bufferp->datap, 0, + buf_bufferSize); + bufferp->dataVersion = scp->dataVersion; + } + + if (cm_HaveBuffer(scp, bufferp, 1)) break; + + /* otherwise, load the buffer and try again */ + lock_ReleaseMutex(&bufferp->mx); + code = cm_GetBuffer(scp, bufferp, NULL, userp, + &req); + lock_ReleaseMutex(&scp->mx); + lock_ObtainMutex(&bufferp->mx); + lock_ObtainMutex(&scp->mx); + if (code) + break; + } + if (code) { + lock_ReleaseMutex(&bufferp->mx); + buf_Release(bufferp); + bufferp = NULL; + goto done; + } + } /* if (wrong buffer) ... */ + + /* now we have the right buffer loaded. Copy out the + * data from here to the user's buffer. + */ + bufIndex = offset.LowPart & (buf_bufferSize - 1); + + /* and figure out how many bytes we want from this buffer */ + nbytes = buf_bufferSize - bufIndex; /* what remains in buffer */ + if (nbytes > count) + nbytes = count; /* don't go past end of request */ + + /* now copy the data */ #ifdef DJGPP - if (dosflag) - dosmemget((dos_ptr)op, nbytes, bufferp->datap + bufIndex); - else + if (dosflag) + dosmemget((dos_ptr)op, nbytes, bufferp->datap + bufIndex); + else #endif /* DJGPP */ - memcpy(bufferp->datap + bufIndex, op, nbytes); - buf_SetDirty(bufferp); + memcpy(bufferp->datap + bufIndex, op, nbytes); + buf_SetDirty(bufferp); - /* and record the last writer */ - if (bufferp->userp != userp) { - cm_HoldUser(userp); - if (bufferp->userp) + /* and record the last writer */ + if (bufferp->userp != userp) { + cm_HoldUser(userp); + if (bufferp->userp) cm_ReleaseUser(bufferp->userp); - bufferp->userp = userp; - } - - /* adjust counters, pointers, etc. */ - op += nbytes; - count -= nbytes; - written += nbytes; - thyper.LowPart = nbytes; - thyper.HighPart = 0; - offset = LargeIntegerAdd(thyper, offset); - } /* while 1 */ + bufferp->userp = userp; + } + + /* adjust counters, pointers, etc. */ + op += nbytes; + count -= nbytes; + written += nbytes; + thyper.LowPart = nbytes; + thyper.HighPart = 0; + offset = LargeIntegerAdd(thyper, offset); + } /* while 1 */ done: - lock_ReleaseMutex(&scp->mx); - if (bufferp) { - lock_ReleaseMutex(&bufferp->mx); - buf_Release(bufferp); - } - - if (code == 0 /* && filter != 0 && (fidp->flags & SMB_FID_NTOPEN) - && (fidp->NTopen_dscp->flags & CM_SCACHEFLAG_ANYWATCH)*/) { - /*smb_NotifyChange(FILE_ACTION_MODIFIED, filter, - fidp->NTopen_dscp, fidp->NTopen_pathp, - NULL, TRUE);*/ - } - - if (code == 0 && doWriteBack) { - lock_ObtainMutex(&scp->mx); - cm_SyncOp(scp, NULL, userp, &req, 0, CM_SCACHESYNC_ASYNCSTORE); - lock_ReleaseMutex(&scp->mx); - cm_QueueBKGRequest(scp, cm_BkgStore, writeBackOffset.LowPart, - writeBackOffset.HighPart, cm_chunkSize, 0, userp); - } - - return code; + lock_ReleaseMutex(&scp->mx); + if (bufferp) { + lock_ReleaseMutex(&bufferp->mx); + buf_Release(bufferp); + } + +#if 0 + if (code == 0 /* && filter != 0 && (fidp->flags & SMB_FID_NTOPEN) + && (fidp->NTopen_dscp->flags & CM_SCACHEFLAG_ANYWATCH)*/) { + smb_NotifyChange(FILE_ACTION_MODIFIED, filter, + fidp->NTopen_dscp, fidp->NTopen_pathp, + NULL, TRUE); + } +#endif + + if (code == 0 && doWriteBack) { + lock_ObtainMutex(&scp->mx); + cm_SyncOp(scp, NULL, userp, &req, 0, CM_SCACHESYNC_ASYNCSTORE); + lock_ReleaseMutex(&scp->mx); + cm_QueueBKGRequest(scp, cm_BkgStore, writeBackOffset.LowPart, + writeBackOffset.HighPart, cm_chunkSize, 0, userp); + } + + return code; } diff --git a/src/WINNT/afsrdr/afsrdr.c b/src/WINNT/afsrdr/afsrdr.c index e5c01e9ab..bc00ec5bb 100644 --- a/src/WINNT/afsrdr/afsrdr.c +++ b/src/WINNT/afsrdr/afsrdr.c @@ -36,7 +36,7 @@ */ #define IRPMJFUNCDESC /* pull in text strings of the names of irp codes */ -#define RPC_SRV /* which half of the rpc library to use */ +#define RPC_SRV /* which half of the rpc library to use */ #include #include @@ -62,31 +62,31 @@ IoAllocateDriverObjectExtension( /*** local structs ***/ /* represents a specific file */ struct afs_fcb - { - FSRTL_COMMON_FCB_HEADER; /* needed to interface with cache manager, etc. */ - SECTION_OBJECT_POINTERS sectionPtrs; - ERESOURCE _resource; /* pointed to by fcb_header->Resource */ - ERESOURCE _pagingIoResource; - unsigned long fid; /* a courtesy from the userland daemon (a good hash function) */ - UCHAR delPending; /* 3 types: FIX */ - struct afs_ccb *ccb_list; /* list of open instances */ - SHARE_ACCESS share_access; /* common access control */ - }; +{ + FSRTL_COMMON_FCB_HEADER; /* needed to interface with cache manager, etc. */ + SECTION_OBJECT_POINTERS sectionPtrs; + ERESOURCE _resource; /* pointed to by fcb_header->Resource */ + ERESOURCE _pagingIoResource; + unsigned long fid; /* a courtesy from the userland daemon (a good hash function) */ + UCHAR delPending; /* 3 types: FIX */ + struct afs_ccb *ccb_list; /* list of open instances */ + SHARE_ACCESS share_access; /* common access control */ +}; typedef struct afs_fcb afs_fcb_t; /* represents an open instance of a file */ struct afs_ccb - { - struct afs_ccb *next; /* these are chained as siblings, non-circularly */ - ULONG access; /* how this instance is opened */ - wchar_t *name; /* ptr to name buffer */ - UNICODE_STRING str; /* full name struct, for notification fns */ - FILE_OBJECT *fo; /* can get parent fcb from this */ - LARGE_INTEGER cookie; /* on enum ops, where we are */ - wchar_t *filter; /* on enum ops, what we are filtering on */ - PACCESS_TOKEN token; /* security data of opening app */ - ULONG attribs; /* is dir, etc. */ - }; +{ + struct afs_ccb *next; /* these are chained as siblings, non-circularly */ + ULONG access; /* how this instance is opened */ + wchar_t *name; /* ptr to name buffer */ + UNICODE_STRING str; /* full name struct, for notification fns */ + FILE_OBJECT *fo; /* can get parent fcb from this */ + LARGE_INTEGER cookie; /* on enum ops, where we are */ + wchar_t *filter; /* on enum ops, what we are filtering on */ + PACCESS_TOKEN token; /* security data of opening app */ + ULONG attribs; /* is dir, etc. */ +}; typedef struct afs_ccb afs_ccb_t; @@ -141,97 +141,97 @@ struct ComExtension *comExt; #define LOCK_FCB_LIST FsRtlEnterFileSystem(); ExAcquireFastMutex(&rdrExt->fcbLock); #define UNLOCK_FCB_LIST ExReleaseFastMutex(&rdrExt->fcbLock); FsRtlExitFileSystem(); -#define LOCK_FCB ExAcquireResourceExclusiveLite(fcb->Resource, TRUE) -#define SLOCK_FCB ExAcquireResourceSharedLite(fcb->Resource, TRUE) -#define UNLOCK_FCB if (fcb) ExReleaseResourceLite(fcb->Resource) +#define LOCK_FCB ExAcquireResourceExclusiveLite(fcb->Resource, TRUE) +#define SLOCK_FCB ExAcquireResourceSharedLite(fcb->Resource, TRUE) +#define UNLOCK_FCB if (fcb) ExReleaseResourceLite(fcb->Resource) #define LOCK_PAGING_FCB ExAcquireResourceExclusiveLite(fcb->PagingIoResource, TRUE) #define SLOCK_PAGING_FCB ExAcquireResourceSharedLite(fcb->PagingIoResource, TRUE) #define UNLOCK_PAGING_FCB if (fcb) ExReleaseResourceLite(fcb->PagingIoResource) /*** constants ***/ -#define AFS_RDR_TAG (0x73666440)//@dfs//0x482ac230//0x3029a4f2 -#define MAX_PATH 700 -#define AFS_FS_NAME L"Andrew File System" +#define AFS_RDR_TAG (0x73666440)//@dfs//0x482ac230//0x3029a4f2 +#define MAX_PATH 700 +#define AFS_FS_NAME L"Andrew File System" -#define COMM_IOCTL (void*)0x01 +#define COMM_IOCTL (void*)0x01 #define COMM_DOWNCALL (void*)0x02 #define COMM_UPCALLHOOK (void*)0x03 -/*#define ACC_READ (STANDARD_RIGHTS_READ | FILE_READ_DATA | FILE_LIST_DIRECTORY -#define ACC_WRITE (STANDARD_RIGHTS_WRITE | FILE_WRITE_DATA)* +/*#define ACC_READ (STANDARD_RIGHTS_READ | FILE_READ_DATA | FILE_LIST_DIRECTORY +#define ACC_WRITE (STANDARD_RIGHTS_WRITE | FILE_WRITE_DATA)* -/* dates from afs are time_t style -- seconds since 1970 */ /* 11644505691.6384 */ +/* dates from afs are time_t style -- seconds since 1970 */ /* 11644505691.6384 */ #define AfsTimeToWindowsTime(x) (((x)+11644505692L)*10000000L) /*(1970L-1601L)*365.242199*24L*3600L)*/ #define WindowsTimeToAfsTime(x) ((x)/10000000L-11644505692L) /*(1970L-1601L)*365.242199*24L*3600L)*/ -#define IsDeviceFile(fo) (!fo->FsContext) +#define IsDeviceFile(fo) (!fo->FsContext) /*** auxiliary functions ***/ #define COMPLETE_NO_BOOST IoCompleteRequest(Irp, IO_NO_INCREMENT) -#define COMPLETE IoCompleteRequest(Irp, IO_NETWORK_INCREMENT) +#define COMPLETE IoCompleteRequest(Irp, IO_NETWORK_INCREMENT) afs_fcb_t *FindFcb(FILE_OBJECT *fo) - { - if (fo) - return fo->FsContext; - return NULL; - } +{ + if (fo) + return fo->FsContext; + return NULL; +} void *AfsFindBuffer(IRP *Irp) - { - void *outPtr; - if (Irp->MdlAddress) - { - outPtr = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority); - if (outPtr) - return outPtr; - } - outPtr = Irp->AssociatedIrp.SystemBuffer; - return outPtr; - } +{ + void *outPtr; + if (Irp->MdlAddress) + { + outPtr = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority); + if (outPtr) + return outPtr; + } + outPtr = Irp->AssociatedIrp.SystemBuffer; + return outPtr; +} /* we do Resource locking because we don't want to figure out when to pull MainResource */ BOOLEAN lazyWriteLock(PVOID context, BOOLEAN wait) { -afs_fcb_t *fcb = context; -ASSERT(fcb); -return ExAcquireResourceExclusiveLite(fcb->Resource, wait); + afs_fcb_t *fcb = context; + ASSERT(fcb); + return ExAcquireResourceExclusiveLite(fcb->Resource, wait); } void lazyWriteUnlock(PVOID context) { -afs_fcb_t *fcb = context; -ASSERT(fcb); -ExReleaseResourceLite(fcb->Resource); + afs_fcb_t *fcb = context; + ASSERT(fcb); + ExReleaseResourceLite(fcb->Resource); } BOOLEAN readAheadLock(PVOID context, BOOLEAN wait) { -afs_fcb_t *fcb = context; -ASSERT(fcb); -return ExAcquireResourceSharedLite(fcb->Resource, wait); + afs_fcb_t *fcb = context; + ASSERT(fcb); + return ExAcquireResourceSharedLite(fcb->Resource, wait); } void readAheadUnlock(PVOID context) { -afs_fcb_t *fcb = context; -ASSERT(fcb); -ExReleaseResourceLite(fcb->Resource); + afs_fcb_t *fcb = context; + ASSERT(fcb); + ExReleaseResourceLite(fcb->Resource); } afs_fcb_t *find_fcb(ULONG fid) { -afs_fcb_t compare, *compare_ptr, **fcbp; + afs_fcb_t compare, *compare_ptr, **fcbp; -compare.fid = fid; -compare_ptr = &compare; -fcbp = RtlLookupElementGenericTable(&rdrExt->fcbTable, (void*)&compare_ptr); + compare.fid = fid; + compare_ptr = &compare; + fcbp = RtlLookupElementGenericTable(&rdrExt->fcbTable, (void*)&compare_ptr); -if (fcbp) + if (fcbp) return (*fcbp); -return NULL; + return NULL; } @@ -245,487 +245,498 @@ return NULL; **********************************************************/ NTSTATUS AfsRdrCreate(DEVICE_OBJECT *DeviceObject, IRP *Irp, IO_STACK_LOCATION *IrpSp, afs_fcb_t *_fcb) { -afs_fcb_t *pfcb, *fcb, **fcbp; -afs_ccb_t *ccb, *pccb; -ULONG len, x, y; -wchar_t *str, *ptr; -ULONG fid, access, granted, disp; -LARGE_INTEGER size, creation, accesst, change, written, zero; -ULONG attribs; -ULONG share; -CC_FILE_SIZES sizes; -NTSTATUS status; -char created; -PACCESS_TOKEN acc_token; - -/* set rpc security context for current thread */ -acc_token = SeQuerySubjectContextToken(&IrpSp->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext); -ASSERT(acc_token); -rpc_set_context(acc_token); - -/* attempt to open afs volume directly */ -if (IrpSp->FileObject->FileName.Length == 0) + afs_fcb_t *pfcb, *fcb, **fcbp; + afs_ccb_t *ccb, *pccb; + ULONG len; + LONG x, y; + wchar_t *str, *ptr; + ULONG fid, access, granted, disp; + LARGE_INTEGER size, creation, accesst, change, written, zero; + ULONG attribs; + ULONG share; + CC_FILE_SIZES sizes; + NTSTATUS status; + char created; + PACCESS_TOKEN acc_token; + + /* set rpc security context for current thread */ + acc_token = SeQuerySubjectContextToken(&IrpSp->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext); + ASSERT(acc_token); + rpc_set_context(acc_token); + + /* attempt to open afs volume directly */ + if (IrpSp->FileObject->FileName.Length == 0) SYNC_FAIL(STATUS_SHARING_VIOLATION); -if (IrpSp->FileObject->FileName.Length > MAX_PATH*sizeof(wchar_t)) + if (IrpSp->FileObject->FileName.Length > MAX_PATH*sizeof(wchar_t)) SYNC_FAIL(STATUS_OBJECT_NAME_INVALID); -if (IrpSp->Parameters.Create.FileAttributes & FILE_ATTRIBUTE_TEMPORARY && + if (IrpSp->Parameters.Create.FileAttributes & FILE_ATTRIBUTE_TEMPORARY && IrpSp->Parameters.Create.Options & FILE_DIRECTORY_FILE) SYNC_FAIL(STATUS_INVALID_PARAMETER); -/* relative opens cannot start with \ */ -if (IrpSp->FileObject->RelatedFileObject && + /* relative opens cannot start with \ */ + if (IrpSp->FileObject->RelatedFileObject && IrpSp->FileObject->FileName.Length && IrpSp->FileObject->FileName.Buffer[0] == L'\\') SYNC_FAIL(STATUS_INVALID_PARAMETER);/*STATUS_OBJECT_PATH_SYNTAX_BAD);*/ -/* a create request can be relative to a prior file. build filename here */ -pccb = NULL; -if (IrpSp->FileObject->RelatedFileObject) + /* a create request can be relative to a prior file. build filename here */ + pccb = NULL; + if (IrpSp->FileObject->RelatedFileObject) pccb = IrpSp->FileObject->RelatedFileObject->FsContext2; -len = IrpSp->FileObject->FileName.Length + (pccb?wcslen(pccb->name):0)*sizeof(wchar_t) + 6; -str = ExAllocatePoolWithTag(NonPagedPool, len, AFS_RDR_TAG); -RtlZeroMemory(str, len); -if (pccb) - { + len = IrpSp->FileObject->FileName.Length + (pccb?wcslen(pccb->name):0)*sizeof(wchar_t) + 6; + str = ExAllocatePoolWithTag(NonPagedPool, len, AFS_RDR_TAG); + RtlZeroMemory(str, len); + if (pccb) + { StringCbCatN(str, len, IrpSp->FileObject->RelatedFileObject->FileName.Buffer, IrpSp->FileObject->RelatedFileObject->FileName.Length); StringCbCat(str, len, L"\\"); - } -StringCbCatN(str, len, IrpSp->FileObject->FileName.Buffer, IrpSp->FileObject->FileName.Length); + } + StringCbCatN(str, len, IrpSp->FileObject->FileName.Buffer, IrpSp->FileObject->FileName.Length); -/* request to open heirarchical parent of specified path */ -/* remove last path component */ -if (IrpSp->Flags & SL_OPEN_TARGET_DIRECTORY) - { + /* request to open heirarchical parent of specified path */ + /* remove last path component */ + if (IrpSp->Flags & SL_OPEN_TARGET_DIRECTORY) + { y = x = wcslen(str); if (x) - x--, y--; + x--, y--; for (x; x >= 0; x--) - { - if (str[x] == L'\\') - { - if (y == x && x != 0) - str[x] = L'\0'; - else if (x != 0) - { - str[x] = L'\0'; - break; - } - else - { - str[x+1] = L'\0'; - break; - } - } - } - } - -/* first two characters are \%01d . %d is number of path components immediately - following that should not be returned in file name queries. - EX: \3\mount\path\start\fname.ext is mapped to :\fname.ext */ -if (wcslen(str) <= 2) - { + { + if (str[x] == L'\\') + { + if (y == x && x != 0) + str[x] = L'\0'; + else if (x != 0) + { + str[x] = L'\0'; + break; + } + else + { + str[x+1] = L'\0'; + break; + } + } + } + } + + /* first two characters are \%01d . %d is number of path components immediately + * following that should not be returned in file name queries. + * EX: \3\mount\path\start\fname.ext is mapped to :\fname.ext + */ + if (wcslen(str) <= 2) + { ExFreePoolWithTag(str, AFS_RDR_TAG); SYNC_FAIL(STATUS_OBJECT_NAME_INVALID); - } - -fid = 0; -disp = (unsigned char)((IrpSp->Parameters.Create.Options >> 24) & 0xff); -access = IrpSp->Parameters.Create.SecurityContext->DesiredAccess; -share = IrpSp->Parameters.Create.ShareAccess; -size.QuadPart = 0; -created = 0; - -/* check for file existance. we jump to creating it if needed */ -if (disp == FILE_OPEN || disp == FILE_OPEN_IF || disp == FILE_OVERWRITE || - disp == FILE_OVERWRITE_IF || disp == FILE_SUPERSEDE) - { + } + + fid = 0; + disp = (unsigned char)((IrpSp->Parameters.Create.Options >> 24) & 0xff); + access = IrpSp->Parameters.Create.SecurityContext->DesiredAccess; + share = IrpSp->Parameters.Create.ShareAccess; + size.QuadPart = 0; + created = 0; + + /* check for file existance. we jump to creating it if needed */ + if (disp == FILE_OPEN || disp == FILE_OPEN_IF || disp == FILE_OVERWRITE || + disp == FILE_OVERWRITE_IF || disp == FILE_SUPERSEDE) + { /* chop our internal mount flagging from the beginning */ status = uc_namei(str+2, &fid); if (status == IFSL_DOES_NOT_EXIST && - (disp == FILE_OPEN_IF || - disp == FILE_OVERWRITE_IF || - disp == FILE_SUPERSEDE)) - goto create; + (disp == FILE_OPEN_IF || + disp == FILE_OVERWRITE_IF || + disp == FILE_SUPERSEDE)) + goto create; if (status != IFSL_SUCCESS) - { - ExFreePoolWithTag(str, AFS_RDR_TAG); - switch (status) - { - case IFSL_RPC_TIMEOUT: SYNC_FAIL_RPC_TIMEOUT; - case IFSL_NO_ACCESS: SYNC_FAIL(STATUS_ACCESS_DENIED); - case IFSL_BAD_INPUT: SYNC_FAIL(STATUS_INVALID_PARAMETER); - case IFSL_DOES_NOT_EXIST: SYNC_FAIL2(STATUS_OBJECT_NAME_NOT_FOUND, FILE_DOES_NOT_EXIST); - case IFSL_PATH_DOES_NOT_EXIST: SYNC_FAIL2(STATUS_OBJECT_PATH_NOT_FOUND, FILE_DOES_NOT_EXIST); - default: SYNC_FAIL(STATUS_UNSUCCESSFUL); - } - } + { + ExFreePoolWithTag(str, AFS_RDR_TAG); + switch (status) + { + case IFSL_RPC_TIMEOUT: SYNC_FAIL_RPC_TIMEOUT; + case IFSL_NO_ACCESS: SYNC_FAIL(STATUS_ACCESS_DENIED); + case IFSL_BAD_INPUT: SYNC_FAIL(STATUS_INVALID_PARAMETER); + case IFSL_DOES_NOT_EXIST: SYNC_FAIL2(STATUS_OBJECT_NAME_NOT_FOUND, FILE_DOES_NOT_EXIST); + case IFSL_PATH_DOES_NOT_EXIST: SYNC_FAIL2(STATUS_OBJECT_PATH_NOT_FOUND, FILE_DOES_NOT_EXIST); + default: SYNC_FAIL(STATUS_UNSUCCESSFUL); + } + } /* make upcall to get ACL in afs. we specify our requested level to - keep it from hitting the network on a public volume. */ + * keep it from hitting the network on a public volume. + */ status = uc_check_access(fid, access, &granted); if (status != IFSL_SUCCESS) - { - ExFreePoolWithTag(str, AFS_RDR_TAG); - switch (status) - { - case IFSL_RPC_TIMEOUT: SYNC_FAIL_RPC_TIMEOUT; - case IFSL_BAD_INPUT: SYNC_FAIL(STATUS_INVALID_PARAMETER); - default: SYNC_FAIL(STATUS_UNSUCCESSFUL); - } - } + { + ExFreePoolWithTag(str, AFS_RDR_TAG); + switch (status) + { + case IFSL_RPC_TIMEOUT: SYNC_FAIL_RPC_TIMEOUT; + case IFSL_BAD_INPUT: SYNC_FAIL(STATUS_INVALID_PARAMETER); + default: SYNC_FAIL(STATUS_UNSUCCESSFUL); + } + } /* make sure daemon approved access */ if ((access & granted) != access) - { - ExFreePoolWithTag(str, AFS_RDR_TAG); - SYNC_FAIL(STATUS_ACCESS_DENIED); - } + { + ExFreePoolWithTag(str, AFS_RDR_TAG); + SYNC_FAIL(STATUS_ACCESS_DENIED); + } /* we depend on this information for caching, etc. */ status = uc_stat(fid, &attribs, &size, &creation, &accesst, &change, &written); if (status != IFSL_SUCCESS) - { - ExFreePoolWithTag(str, AFS_RDR_TAG); - switch (status) - { - case IFSL_RPC_TIMEOUT: SYNC_FAIL_RPC_TIMEOUT; - case IFSL_BAD_INPUT: SYNC_FAIL(STATUS_INVALID_PARAMETER); - default: SYNC_FAIL(STATUS_UNSUCCESSFUL); - } - } + { + ExFreePoolWithTag(str, AFS_RDR_TAG); + switch (status) + { + case IFSL_RPC_TIMEOUT: SYNC_FAIL_RPC_TIMEOUT; + case IFSL_BAD_INPUT: SYNC_FAIL(STATUS_INVALID_PARAMETER); + default: SYNC_FAIL(STATUS_UNSUCCESSFUL); + } + } /* afsd does not maintain instance-specific data, so we adjust here */ if (granted & FILE_READ_DATA && !(granted & FILE_WRITE_DATA)) - attribs |= FILE_ATTRIBUTE_READONLY; + attribs |= FILE_ATTRIBUTE_READONLY; if (IrpSp->Parameters.Create.Options & FILE_DIRECTORY_FILE && - !(attribs & FILE_ATTRIBUTE_DIRECTORY)) - { - ExFreePoolWithTag(str, AFS_RDR_TAG); - SYNC_FAIL(STATUS_NOT_A_DIRECTORY); - } + !(attribs & FILE_ATTRIBUTE_DIRECTORY)) + { + ExFreePoolWithTag(str, AFS_RDR_TAG); + SYNC_FAIL(STATUS_NOT_A_DIRECTORY); + } if (IrpSp->Parameters.Create.Options & FILE_NON_DIRECTORY_FILE && - attribs & FILE_ATTRIBUTE_DIRECTORY) - { - ExFreePoolWithTag(str, AFS_RDR_TAG); - SYNC_FAIL(STATUS_FILE_IS_A_DIRECTORY); - } + attribs & FILE_ATTRIBUTE_DIRECTORY) + { + ExFreePoolWithTag(str, AFS_RDR_TAG); + SYNC_FAIL(STATUS_FILE_IS_A_DIRECTORY); + } /* check for previous open instance(s) of file. it will be in the fcb chain. - when we have this locked, we cannot make upcalls -- running at APC_LEVEL. - lock here (not later) to prevent possible truncation races. */ + * when we have this locked, we cannot make upcalls -- running at APC_LEVEL. + * lock here (not later) to prevent possible truncation races. + */ LOCK_FCB_LIST; fcb = find_fcb(fid); if (fcb) - { - LOCK_PAGING_FCB; - LOCK_FCB; - } + { + LOCK_PAGING_FCB; + LOCK_FCB; + } /* if we found it, check to make sure open disposition and sharing - are not in conflict with previous opens. then, make new file - instance entry and, if necessary, file entry. */ + * are not in conflict with previous opens. then, make new file + * instance entry and, if necessary, file entry. + */ if (fcb) - { - /* file contents cannot be cached for a successful delete */ - if (access & FILE_WRITE_DATA) - if (!MmFlushImageSection(&(fcb->sectionPtrs), MmFlushForWrite)) - { - UNLOCK_FCB; - UNLOCK_PAGING_FCB; - UNLOCK_FCB_LIST; - ExFreePoolWithTag(str, AFS_RDR_TAG); - SYNC_FAIL(STATUS_SHARING_VIOLATION); - } - if (access & DELETE) - if (!MmFlushImageSection(&(fcb->sectionPtrs), MmFlushForWrite))//Delete)) - { - UNLOCK_FCB; - UNLOCK_PAGING_FCB; - UNLOCK_FCB_LIST; - ExFreePoolWithTag(str, AFS_RDR_TAG); - SYNC_FAIL(STATUS_SHARING_VIOLATION); - } - - /* check common sharing flags, but do not change */ - if (IoCheckShareAccess(access, share, IrpSp->FileObject, &fcb->share_access, FALSE) != STATUS_SUCCESS) - { - rpt0(("create", "sharing violation for %ws", str)); - UNLOCK_FCB; - UNLOCK_PAGING_FCB; - UNLOCK_FCB_LIST; - ExFreePoolWithTag(str, AFS_RDR_TAG); - SYNC_FAIL(STATUS_SHARING_VIOLATION); - } - - zero.QuadPart = 0; - if (access & DELETE) - if (!MmCanFileBeTruncated(&(fcb->sectionPtrs), &zero)) - { - UNLOCK_FCB; - UNLOCK_PAGING_FCB; - UNLOCK_FCB_LIST; - ExFreePoolWithTag(str, AFS_RDR_TAG); - SYNC_FAIL(STATUS_SHARING_VIOLATION); - } - } + { + /* file contents cannot be cached for a successful delete */ + if (access & FILE_WRITE_DATA) + if (!MmFlushImageSection(&(fcb->sectionPtrs), MmFlushForWrite)) + { + UNLOCK_FCB; + UNLOCK_PAGING_FCB; + UNLOCK_FCB_LIST; + ExFreePoolWithTag(str, AFS_RDR_TAG); + SYNC_FAIL(STATUS_SHARING_VIOLATION); + } + if (access & DELETE) + if (!MmFlushImageSection(&(fcb->sectionPtrs), MmFlushForWrite))//Delete)) + { + UNLOCK_FCB; + UNLOCK_PAGING_FCB; + UNLOCK_FCB_LIST; + ExFreePoolWithTag(str, AFS_RDR_TAG); + SYNC_FAIL(STATUS_SHARING_VIOLATION); + } + + /* check common sharing flags, but do not change */ + if (IoCheckShareAccess(access, share, IrpSp->FileObject, &fcb->share_access, FALSE) != STATUS_SUCCESS) + { + rpt0(("create", "sharing violation for %ws", str)); + UNLOCK_FCB; + UNLOCK_PAGING_FCB; + UNLOCK_FCB_LIST; + ExFreePoolWithTag(str, AFS_RDR_TAG); + SYNC_FAIL(STATUS_SHARING_VIOLATION); + } + + zero.QuadPart = 0; + if (access & DELETE) + if (!MmCanFileBeTruncated(&(fcb->sectionPtrs), &zero)) + { + UNLOCK_FCB; + UNLOCK_PAGING_FCB; + UNLOCK_FCB_LIST; + ExFreePoolWithTag(str, AFS_RDR_TAG); + SYNC_FAIL(STATUS_SHARING_VIOLATION); + } + } /* do overwrite/supersede tasks */ if (disp == FILE_OVERWRITE || - disp == FILE_OVERWRITE_IF || - disp == FILE_SUPERSEDE) - { - zero.QuadPart = 0; - if (fcb && !MmCanFileBeTruncated(&(fcb->sectionPtrs), &zero)) - { - UNLOCK_FCB; - UNLOCK_PAGING_FCB; - UNLOCK_FCB_LIST; - ExFreePoolWithTag(str, AFS_RDR_TAG); - SYNC_FAIL(STATUS_SHARING_VIOLATION); - } - if (size.QuadPart != 0) - { - size.QuadPart = 0; - status = uc_trunc(fid, size); - if (status != IFSL_SUCCESS) - { - UNLOCK_FCB; - UNLOCK_PAGING_FCB; - UNLOCK_FCB_LIST; - ExFreePoolWithTag(str, AFS_RDR_TAG); - SYNC_FAIL(STATUS_ACCESS_DENIED); - } - if (fcb) - { - fcb->AllocationSize = fcb->FileSize = fcb->ValidDataLength = size; - CcSetFileSizes(IrpSp->FileObject, (CC_FILE_SIZES*)&fcb->AllocationSize); - } - } - if (Irp->Overlay.AllocationSize.QuadPart) - { - status = uc_trunc(fid, Irp->Overlay.AllocationSize); - size = Irp->Overlay.AllocationSize; - if (status != IFSL_SUCCESS) - { - UNLOCK_FCB; - UNLOCK_PAGING_FCB; - UNLOCK_FCB_LIST; - ExFreePoolWithTag(str, AFS_RDR_TAG); - SYNC_FAIL(STATUS_DISK_FULL); - } - if (fcb) - { - fcb->AllocationSize = fcb->FileSize = fcb->ValidDataLength = size; - CcSetFileSizes(IrpSp->FileObject, (CC_FILE_SIZES*)&fcb->AllocationSize); - } - } - } + disp == FILE_OVERWRITE_IF || + disp == FILE_SUPERSEDE) + { + zero.QuadPart = 0; + if (fcb && !MmCanFileBeTruncated(&(fcb->sectionPtrs), &zero)) + { + UNLOCK_FCB; + UNLOCK_PAGING_FCB; + UNLOCK_FCB_LIST; + ExFreePoolWithTag(str, AFS_RDR_TAG); + SYNC_FAIL(STATUS_SHARING_VIOLATION); + } + if (size.QuadPart != 0) + { + size.QuadPart = 0; + status = uc_trunc(fid, size); + if (status != IFSL_SUCCESS) + { + UNLOCK_FCB; + UNLOCK_PAGING_FCB; + UNLOCK_FCB_LIST; + ExFreePoolWithTag(str, AFS_RDR_TAG); + SYNC_FAIL(STATUS_ACCESS_DENIED); + } + if (fcb) + { + fcb->AllocationSize = fcb->FileSize = fcb->ValidDataLength = size; + CcSetFileSizes(IrpSp->FileObject, (CC_FILE_SIZES*)&fcb->AllocationSize); + } + } + if (Irp->Overlay.AllocationSize.QuadPart) + { + status = uc_trunc(fid, Irp->Overlay.AllocationSize); + size = Irp->Overlay.AllocationSize; + if (status != IFSL_SUCCESS) + { + UNLOCK_FCB; + UNLOCK_PAGING_FCB; + UNLOCK_FCB_LIST; + ExFreePoolWithTag(str, AFS_RDR_TAG); + SYNC_FAIL(STATUS_DISK_FULL); + } + if (fcb) + { + fcb->AllocationSize = fcb->FileSize = fcb->ValidDataLength = size; + CcSetFileSizes(IrpSp->FileObject, (CC_FILE_SIZES*)&fcb->AllocationSize); + } + } + } if (fcb) - { - /* make actual change in common sharing flags */ - IoUpdateShareAccess(IrpSp->FileObject, &fcb->share_access); - goto makeccb; - } + { + /* make actual change in common sharing flags */ + IoUpdateShareAccess(IrpSp->FileObject, &fcb->share_access); + goto makeccb; + } goto makefcb; - } + } -/* if disposition was to create the file, or its non-existance necessitates this */ -create: -if (disp == FILE_CREATE || - status == IFSL_DOES_NOT_EXIST && (disp == FILE_OPEN_IF || disp == FILE_OVERWRITE_IF || disp == FILE_SUPERSEDE)) - { + /* if disposition was to create the file, or its non-existance necessitates this */ + create: + if (disp == FILE_CREATE || + status == IFSL_DOES_NOT_EXIST && (disp == FILE_OPEN_IF || disp == FILE_OVERWRITE_IF || disp == FILE_SUPERSEDE)) + { attribs = IrpSp->Parameters.Create.FileAttributes; if (IrpSp->Parameters.Create.Options & FILE_DIRECTORY_FILE) - attribs |= FILE_ATTRIBUTE_DIRECTORY; + attribs |= FILE_ATTRIBUTE_DIRECTORY; if (IrpSp->Parameters.Create.Options & FILE_NON_DIRECTORY_FILE) - attribs &= ~FILE_ATTRIBUTE_DIRECTORY; + attribs &= ~FILE_ATTRIBUTE_DIRECTORY; status = uc_create(str+2, attribs, Irp->Overlay.AllocationSize, access, &granted, &fid); if (status != IFSL_SUCCESS) - { - ExFreePoolWithTag(str, AFS_RDR_TAG); - switch (status) - { - case IFSL_RPC_TIMEOUT: SYNC_FAIL_RPC_TIMEOUT; - case IFSL_NO_ACCESS: SYNC_FAIL(STATUS_ACCESS_DENIED); - case IFSL_BAD_INPUT: SYNC_FAIL(STATUS_INVALID_PARAMETER); - case IFSL_PATH_DOES_NOT_EXIST: SYNC_FAIL2(STATUS_OBJECT_PATH_NOT_FOUND, FILE_DOES_NOT_EXIST); - case IFSL_OPEN_EXISTS: SYNC_FAIL2(STATUS_OBJECT_NAME_COLLISION, FILE_EXISTS); - case IFSL_OVERQUOTA: SYNC_FAIL(STATUS_DISK_FULL);//STATUS_QUOTA_EXCEEDED); - default: SYNC_FAIL(STATUS_UNSUCCESSFUL); - } - } + { + ExFreePoolWithTag(str, AFS_RDR_TAG); + switch (status) + { + case IFSL_RPC_TIMEOUT: SYNC_FAIL_RPC_TIMEOUT; + case IFSL_NO_ACCESS: SYNC_FAIL(STATUS_ACCESS_DENIED); + case IFSL_BAD_INPUT: SYNC_FAIL(STATUS_INVALID_PARAMETER); + case IFSL_PATH_DOES_NOT_EXIST: SYNC_FAIL2(STATUS_OBJECT_PATH_NOT_FOUND, FILE_DOES_NOT_EXIST); + case IFSL_OPEN_EXISTS: SYNC_FAIL2(STATUS_OBJECT_NAME_COLLISION, FILE_EXISTS); + case IFSL_OVERQUOTA: SYNC_FAIL(STATUS_DISK_FULL);//STATUS_QUOTA_EXCEEDED); + default: SYNC_FAIL(STATUS_UNSUCCESSFUL); + } + } /* lock list like above. check again just to make sure it isn't in the list. - if it is, we should process like above. depending on how we follow symlinks - (same fid for multiple files), we cannot expect serialized create requests. */ + * if it is, we should process like above. depending on how we follow symlinks + * (same fid for multiple files), we cannot expect serialized create requests. + */ LOCK_FCB_LIST; fcb = find_fcb(fid); if (fcb) - _asm int 3; + _asm int 3; if (size.QuadPart != 0) - { - size.QuadPart = 0; - uc_trunc(fid, size); - if (status != IFSL_SUCCESS) - { - UNLOCK_FCB_LIST; - ExFreePoolWithTag(str, AFS_RDR_TAG); - SYNC_FAIL(STATUS_DISK_FULL); - } - } + { + size.QuadPart = 0; + uc_trunc(fid, size); + if (status != IFSL_SUCCESS) + { + UNLOCK_FCB_LIST; + ExFreePoolWithTag(str, AFS_RDR_TAG); + SYNC_FAIL(STATUS_DISK_FULL); + } + } if (Irp->Overlay.AllocationSize.QuadPart) - { - uc_trunc(fid, Irp->Overlay.AllocationSize); - size = Irp->Overlay.AllocationSize; - if (status != IFSL_SUCCESS) - { - UNLOCK_FCB_LIST; - ExFreePoolWithTag(str, AFS_RDR_TAG); - SYNC_FAIL(STATUS_ACCESS_DENIED); - } - } + { + uc_trunc(fid, Irp->Overlay.AllocationSize); + size = Irp->Overlay.AllocationSize; + if (status != IFSL_SUCCESS) + { + UNLOCK_FCB_LIST; + ExFreePoolWithTag(str, AFS_RDR_TAG); + SYNC_FAIL(STATUS_ACCESS_DENIED); + } + } created = 1; goto makefcb; - } - -/* OS passed unexpected disposition */ -ExFreePoolWithTag(str, AFS_RDR_TAG); -SYNC_FAIL(STATUS_NOT_IMPLEMENTED); -/*SYNC_FAIL2(STATUS_OBJECT_NAME_NOT_FOUND, FILE_DOES_NOT_EXIST);*/ - - -/* allocate nonpaged struct to track this file and all open instances */ -makefcb: - fcb = ExAllocateFromNPagedLookasideList(&rdrExt->fcbMemList); - ASSERT(fcb); - RtlZeroMemory(fcb, sizeof(afs_fcb_t)); - - fcb->fid = fid; - /*fcb->refs = 0;*/ - fcb->ccb_list = NULL; - fcb->IsFastIoPossible = FastIoIsNotPossible; - - ExInitializeResourceLite(&fcb->_resource); - ExInitializeResourceLite(&fcb->_pagingIoResource); - fcb->Resource = &fcb->_resource; - fcb->PagingIoResource = &fcb->_pagingIoResource; - LOCK_PAGING_FCB; - LOCK_FCB; - - fcb->sectionPtrs.DataSectionObject = NULL; - fcb->sectionPtrs.SharedCacheMap = NULL; - fcb->sectionPtrs.ImageSectionObject = NULL; - fcb->AllocationSize = fcb->FileSize = fcb->ValidDataLength = size; - - IoSetShareAccess(access, share, IrpSp->FileObject, &fcb->share_access); - - /* we store a pointer to the fcb. the table would want to store a copy otherwise. */ - fcbp = &fcb; - RtlInsertElementGenericTable(&rdrExt->fcbTable, fcbp, sizeof(fcbp), NULL); - - sizes.AllocationSize = sizes.FileSize = sizes.ValidDataLength = size; - rpt1(("create", "created size %d name %ws", size.LowPart, str)); - -/* allocate nonpaged struct tracking information specific to (file, open instance) pair, - and link from parent. is put at head of parent's list. */ -makeccb: - /* there are two different types of pending deletes. we return different - errors in places depending on a) delete specified on call to open, - or b) file specifically deleted */ - /* need to check for DELETE perms too? */ - if (IrpSp->Parameters.Create.Options & FILE_DELETE_ON_CLOSE) - fcb->delPending = 2; - - ccb = ExAllocateFromNPagedLookasideList(&rdrExt->ccbMemList); - ccb->name = str; - ccb->access = granted; - ccb->fo = IrpSp->FileObject; - ccb->cookie.QuadPart = 0; - ccb->filter = NULL; - ccb->attribs = attribs; - - /* save security context information. we never change this ccb attribute. */ - ObReferenceObjectByPointer(acc_token, TOKEN_QUERY, NULL, KernelMode); - ccb->token = acc_token; - /*ObOpenObjectByPointer(acc_token, OBJ_KERNEL_HANDLE, NULL, TOKEN_QUERY, NULL, KernelMode, &ccb->token);*/ - - /*fcb->refs++;*/ - if (!fcb->ccb_list) - { - ccb->next = NULL; - fcb->ccb_list = ccb; - } - else - { - ccb->next = fcb->ccb_list; - fcb->ccb_list = ccb; - } - UNLOCK_FCB; - UNLOCK_PAGING_FCB; - UNLOCK_FCB_LIST; - - /* how we pack (as it is expected): a) fscontext same for all open instances of a file, - b) fscontext2 unique among each instance, c) private cache map pointer set by cache - manager upon caching, d) so pointers are per-file, as in (a). */ - IrpSp->FileObject->FsContext = fcb; - IrpSp->FileObject->FsContext2 = ccb; - IrpSp->FileObject->PrivateCacheMap = NULL; - IrpSp->FileObject->SectionObjectPointer = &(fcb->sectionPtrs); - - /* explicitly start caching on a data file. caching will still happen upon - paging i/o even if commented out below. the other option is to cache upon - the first read/write operation. that code is also in place. */ - if (!(attribs & FILE_ATTRIBUTE_DIRECTORY)) - { - /*CcInitializeCacheMap(IrpSp->FileObject, (CC_FILE_SIZES*)&fcb->AllocationSize, FALSE, &rdrExt->callbacks, IrpSp->FileObject->FsContext);//(PVOID)din->Context1);*/ - /*CcSetAdditionalCacheAttributes(IrpSp->FileObject, TRUE, TRUE);*/ - } - - /* customize returns; semantics largely derived from output of ifstest.exe */ - switch (disp) - { - case FILE_OPEN: - SYNC_FAIL2(STATUS_SUCCESS, FILE_OPENED) - - case FILE_OPEN_IF: - if (created) - SYNC_FAIL2(STATUS_SUCCESS, FILE_CREATED) - else - SYNC_FAIL2(STATUS_SUCCESS, FILE_OPENED) - - case FILE_OVERWRITE: - SYNC_FAIL2(STATUS_SUCCESS, FILE_OVERWRITTEN) - - case FILE_OVERWRITE_IF: - if (created) - SYNC_FAIL2(STATUS_SUCCESS, FILE_CREATED) - else - SYNC_FAIL2(STATUS_SUCCESS, FILE_OVERWRITTEN) - - case FILE_SUPERSEDE: - if (created) - SYNC_FAIL2(STATUS_SUCCESS, FILE_CREATED) - else - SYNC_FAIL2(STATUS_SUCCESS, FILE_SUPERSEDED) - - case FILE_CREATE: - SYNC_FAIL2(STATUS_SUCCESS, FILE_CREATED) - } -_asm int 3; -return 0; + } + + /* OS passed unexpected disposition */ + ExFreePoolWithTag(str, AFS_RDR_TAG); + SYNC_FAIL(STATUS_NOT_IMPLEMENTED); + /*SYNC_FAIL2(STATUS_OBJECT_NAME_NOT_FOUND, FILE_DOES_NOT_EXIST);*/ + + + /* allocate nonpaged struct to track this file and all open instances */ + makefcb: + fcb = ExAllocateFromNPagedLookasideList(&rdrExt->fcbMemList); + ASSERT(fcb); + RtlZeroMemory(fcb, sizeof(afs_fcb_t)); + + fcb->fid = fid; + /*fcb->refs = 0;*/ + fcb->ccb_list = NULL; + fcb->IsFastIoPossible = FastIoIsNotPossible; + + ExInitializeResourceLite(&fcb->_resource); + ExInitializeResourceLite(&fcb->_pagingIoResource); + fcb->Resource = &fcb->_resource; + fcb->PagingIoResource = &fcb->_pagingIoResource; + LOCK_PAGING_FCB; + LOCK_FCB; + + fcb->sectionPtrs.DataSectionObject = NULL; + fcb->sectionPtrs.SharedCacheMap = NULL; + fcb->sectionPtrs.ImageSectionObject = NULL; + fcb->AllocationSize = fcb->FileSize = fcb->ValidDataLength = size; + + IoSetShareAccess(access, share, IrpSp->FileObject, &fcb->share_access); + + /* we store a pointer to the fcb. the table would want to store a copy otherwise. */ + fcbp = &fcb; + RtlInsertElementGenericTable(&rdrExt->fcbTable, fcbp, sizeof(fcbp), NULL); + + sizes.AllocationSize = sizes.FileSize = sizes.ValidDataLength = size; + rpt1(("create", "created size %d name %ws", size.LowPart, str)); + + /* allocate nonpaged struct tracking information specific to (file, open instance) pair, + * and link from parent. is put at head of parent's list. + */ + makeccb: + /* there are two different types of pending deletes. we return different + * errors in places depending on a) delete specified on call to open, + * or b) file specifically deleted + */ + /* need to check for DELETE perms too? */ + if (IrpSp->Parameters.Create.Options & FILE_DELETE_ON_CLOSE) + fcb->delPending = 2; + + ccb = ExAllocateFromNPagedLookasideList(&rdrExt->ccbMemList); + ccb->name = str; + ccb->access = granted; + ccb->fo = IrpSp->FileObject; + ccb->cookie.QuadPart = 0; + ccb->filter = NULL; + ccb->attribs = attribs; + + /* save security context information. we never change this ccb attribute. */ + ObReferenceObjectByPointer(acc_token, TOKEN_QUERY, NULL, KernelMode); + ccb->token = acc_token; + /*ObOpenObjectByPointer(acc_token, OBJ_KERNEL_HANDLE, NULL, TOKEN_QUERY, NULL, KernelMode, &ccb->token);*/ + + /*fcb->refs++;*/ + if (!fcb->ccb_list) + { + ccb->next = NULL; + fcb->ccb_list = ccb; + } + else + { + ccb->next = fcb->ccb_list; + fcb->ccb_list = ccb; + } + UNLOCK_FCB; + UNLOCK_PAGING_FCB; + UNLOCK_FCB_LIST; + + /* how we pack (as it is expected): a) fscontext same for all open instances of a file, + * b) fscontext2 unique among each instance, c) private cache map pointer set by cache + * manager upon caching, d) so pointers are per-file, as in (a). + */ + IrpSp->FileObject->FsContext = fcb; + IrpSp->FileObject->FsContext2 = ccb; + IrpSp->FileObject->PrivateCacheMap = NULL; + IrpSp->FileObject->SectionObjectPointer = &(fcb->sectionPtrs); + + /* explicitly start caching on a data file. caching will still happen upon + * paging i/o even if commented out below. the other option is to cache upon + * the first read/write operation. that code is also in place. + */ + if (!(attribs & FILE_ATTRIBUTE_DIRECTORY)) + { + /*CcInitializeCacheMap(IrpSp->FileObject, (CC_FILE_SIZES*)&fcb->AllocationSize, FALSE, &rdrExt->callbacks, IrpSp->FileObject->FsContext);//(PVOID)din->Context1);*/ + /*CcSetAdditionalCacheAttributes(IrpSp->FileObject, TRUE, TRUE);*/ + } + + /* customize returns; semantics largely derived from output of ifstest.exe */ + switch (disp) + { + case FILE_OPEN: + SYNC_FAIL2(STATUS_SUCCESS, FILE_OPENED); + + case FILE_OPEN_IF: + if (created) { + SYNC_FAIL2(STATUS_SUCCESS, FILE_CREATED); + } else { + SYNC_FAIL2(STATUS_SUCCESS, FILE_OPENED); + } + case FILE_OVERWRITE: + SYNC_FAIL2(STATUS_SUCCESS, FILE_OVERWRITTEN); + + case FILE_OVERWRITE_IF: + if (created) { + SYNC_FAIL2(STATUS_SUCCESS, FILE_CREATED); + } else { + SYNC_FAIL2(STATUS_SUCCESS, FILE_OVERWRITTEN); + } + case FILE_SUPERSEDE: + if (created) { + SYNC_FAIL2(STATUS_SUCCESS, FILE_CREATED); + } else { + SYNC_FAIL2(STATUS_SUCCESS, FILE_SUPERSEDED); + } + case FILE_CREATE: + SYNC_FAIL2(STATUS_SUCCESS, FILE_CREATED); + } + _asm int 3; + return 0; } /* experimental; does not work. need to handle filesizes - and cache invalidation in more places. */ + * and cache invalidation in more places. + */ #define EXPLICIT_CACHING /********************************************************** @@ -734,124 +745,125 @@ return 0; **********************************************************/ NTSTATUS AfsRdrRead(DEVICE_OBJECT *DeviceObject, IRP *Irp, IO_STACK_LOCATION *IrpSp, afs_fcb_t *fcb) { -struct ReadKOut *p; -void *ptr; -LARGE_INTEGER offset, curroff; -ULONG length, read; -void *outPtr; -NTSTATUS status; -afs_ccb_t *ccb; -MDL m; -ULONG currpos, ttlread, toread; - -ccb = IrpSp->FileObject->FsContext2; -if (IsDeviceFile(IrpSp->FileObject) || (ccb->attribs & FILE_ATTRIBUTE_DIRECTORY)) + struct ReadKOut *p; + void *ptr; + LARGE_INTEGER offset, curroff; + ULONG length, read; + void *outPtr; + NTSTATUS status; + afs_ccb_t *ccb; + MDL m; + ULONG currpos, ttlread, toread; + + ccb = IrpSp->FileObject->FsContext2; + if (IsDeviceFile(IrpSp->FileObject) || (ccb->attribs & FILE_ATTRIBUTE_DIRECTORY)) SYNC_FAIL(STATUS_INVALID_DEVICE_REQUEST); /* the second line disables read ahead and write behind. since our data is already cached in userland, and there are read-ahead parameters there, we do not use this service. */ #ifdef EXPLICIT_CACHING -if (!IrpSp->FileObject->PrivateCacheMap) - { - CcInitializeCacheMap(IrpSp->FileObject, (CC_FILE_SIZES*)&fcb->AllocationSize, FALSE, &rdrExt->callbacks, IrpSp->FileObject->FsContext);//(PVOID)din->Context1); - CcSetAdditionalCacheAttributes(IrpSp->FileObject, FALSE, TRUE); - //CcSetReadAheadGranularity - } + if (!IrpSp->FileObject->PrivateCacheMap) + { + CcInitializeCacheMap(IrpSp->FileObject, (CC_FILE_SIZES*)&fcb->AllocationSize, FALSE, &rdrExt->callbacks, IrpSp->FileObject->FsContext);//(PVOID)din->Context1); + CcSetAdditionalCacheAttributes(IrpSp->FileObject, FALSE, TRUE); + //CcSetReadAheadGranularity + } #endif -if (!(ccb->access & FILE_READ_DATA) && !(Irp->Flags & IRP_PAGING_IO)) + if (!(ccb->access & FILE_READ_DATA) && !(Irp->Flags & IRP_PAGING_IO)) SYNC_FAIL(STATUS_ACCESS_DENIED); -if (!IrpSp->Parameters.Read.Length) + if (!IrpSp->Parameters.Read.Length) SYNC_FAIL(STATUS_SUCCESS); -offset = IrpSp->Parameters.Read.ByteOffset; -length = IrpSp->Parameters.Read.Length; + offset = IrpSp->Parameters.Read.ByteOffset; + length = IrpSp->Parameters.Read.Length; -/* FIX: lock here, before finding end-of-file */ + /* FIX: lock here, before finding end-of-file */ -/* fast out for reads starting beyond eof */ -if (offset.QuadPart > fcb->ValidDataLength.QuadPart) + /* fast out for reads starting beyond eof */ + if (offset.QuadPart > fcb->ValidDataLength.QuadPart) SYNC_FAIL(STATUS_END_OF_FILE); -/* pre-truncate reads */ -if (offset.QuadPart + length > fcb->ValidDataLength.QuadPart) - length = (ULONG)(fcb->ValidDataLength.QuadPart - offset.QuadPart); + /* pre-truncate reads */ + if (offset.QuadPart + length > fcb->ValidDataLength.QuadPart) + length = (ULONG)(fcb->ValidDataLength.QuadPart - offset.QuadPart); -outPtr = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority); -if (!outPtr) + outPtr = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority); + if (!outPtr) SYNC_FAIL(STATUS_INSUFFICIENT_RESOURCES); #ifdef EXPLICIT_CACHING -if (!(Irp->Flags & (IRP_NOCACHE | IRP_PAGING_IO))) - { + if (!(Irp->Flags & (IRP_NOCACHE | IRP_PAGING_IO))) + { FsRtlEnterFileSystem(); SLOCK_PAGING_FCB; ttlread = 0; try - { - if (!CcCopyRead(IrpSp->FileObject, &offset, length, TRUE, outPtr, &Irp->IoStatus)) - { - UNLOCK_PAGING_FCB; - FsRtlExitFileSystem(); - SYNC_FAIL(STATUS_UNSUCCESSFUL); - } -// KdPrint(("read %x at %x cache done %x\n", length, (ULONG)offset.QuadPart, Irp->IoStatus.Information)); - ttlread = Irp->IoStatus.Information; - } + { + if (!CcCopyRead(IrpSp->FileObject, &offset, length, TRUE, outPtr, &Irp->IoStatus)) + { + UNLOCK_PAGING_FCB; + FsRtlExitFileSystem(); + SYNC_FAIL(STATUS_UNSUCCESSFUL); + } + // KdPrint(("read %x at %x cache done %x\n", length, (ULONG)offset.QuadPart, Irp->IoStatus.Information)); + ttlread = Irp->IoStatus.Information; + } except (EXCEPTION_EXECUTE_HANDLER) - { - STATUS(STATUS_UNSUCCESSFUL, 0); - } + { + STATUS(STATUS_UNSUCCESSFUL, 0); + } UNLOCK_PAGING_FCB; FsRtlExitFileSystem(); if (Irp->IoStatus.Status == STATUS_UNSUCCESSFUL) - SYNC_FAIL(STATUS_UNSUCCESSFUL); - } -else + SYNC_FAIL(STATUS_UNSUCCESSFUL); + } + else #endif - { + { FsRtlEnterFileSystem(); SLOCK_FCB; for (currpos = ttlread = 0; ttlread < length; ) - { - toread = length - currpos; - toread = (toread > TRANSFER_CHUNK_SIZE) ? TRANSFER_CHUNK_SIZE : toread; - curroff.QuadPart = offset.QuadPart + currpos; - status = uc_read(fcb->fid, curroff, toread, &read, outPtr); -// KdPrint(("read %x at %x done %x\n", length, (ULONG)offset.QuadPart, read)); - if (status == 0) - { - ttlread += read; - currpos += read; - if (read < toread) - goto end; - continue; - } - UNLOCK_FCB; - FsRtlExitFileSystem(); - switch (status) - { - case IFSL_RPC_TIMEOUT: SYNC_FAIL_RPC_TIMEOUT; - case IFSL_IS_A_DIR: SYNC_FAIL(STATUS_INVALID_DEVICE_REQUEST); - case IFSL_BAD_INPUT: SYNC_FAIL(STATUS_INVALID_PARAMETER); - default: SYNC_FAIL(STATUS_UNSUCCESSFUL); - } - } -end: ; + { + toread = length - currpos; + toread = (toread > TRANSFER_CHUNK_SIZE) ? TRANSFER_CHUNK_SIZE : toread; + curroff.QuadPart = offset.QuadPart + currpos; + status = uc_read(fcb->fid, curroff, toread, &read, outPtr); + // KdPrint(("read %x at %x done %x\n", length, (ULONG)offset.QuadPart, read)); + if (status == 0) + { + ttlread += read; + currpos += read; + if (read < toread) + goto end; + continue; + } + UNLOCK_FCB; + FsRtlExitFileSystem(); + switch (status) + { + case IFSL_RPC_TIMEOUT: SYNC_FAIL_RPC_TIMEOUT; + case IFSL_IS_A_DIR: SYNC_FAIL(STATUS_INVALID_DEVICE_REQUEST); + case IFSL_BAD_INPUT: SYNC_FAIL(STATUS_INVALID_PARAMETER); + default: SYNC_FAIL(STATUS_UNSUCCESSFUL); + } + } + end: UNLOCK_FCB; FsRtlExitFileSystem(); - } + } -/* update byteoffset when this is not a paging or async request */ -if (IoIsOperationSynchronous(Irp) && !(Irp->Flags & IRP_PAGING_IO)) - IrpSp->FileObject->CurrentByteOffset.QuadPart += ttlread; + /* update byteoffset when this is not a paging or async request */ + if (IoIsOperationSynchronous(Irp) && !(Irp->Flags & IRP_PAGING_IO)) + IrpSp->FileObject->CurrentByteOffset.QuadPart += ttlread; -if (ttlread == 0)//< length) - SYNC_FAIL2(STATUS_END_OF_FILE, ttlread) -else - SYNC_FAIL2(STATUS_SUCCESS, ttlread) -} + if (ttlread == 0 /* was < length*/) { + SYNC_FAIL2(STATUS_END_OF_FILE, ttlread); + } else { + SYNC_FAIL2(STATUS_SUCCESS, ttlread); + } +} @@ -861,220 +873,223 @@ else **********************************************************/ NTSTATUS AfsRdrWrite(DEVICE_OBJECT *DeviceObject, IRP *Irp, IO_STACK_LOCATION *IrpSp, afs_fcb_t *fcb) { -struct WriteKOut *p; -void *ptr, *outPtr; -ULONG length, written; -LARGE_INTEGER offset, end; -NTSTATUS status; -afs_ccb_t *ccb; -CC_FILE_SIZES sizes, oldSizes; -ULONG towrite, ttlwritten, currpos; -LARGE_INTEGER curroff; -BOOLEAN change, paging_lock; - -ccb = IrpSp->FileObject->FsContext2; -if (IsDeviceFile(IrpSp->FileObject) || (ccb->attribs & FILE_ATTRIBUTE_DIRECTORY)) + struct WriteKOut *p; + void *ptr, *outPtr; + ULONG length, written; + LARGE_INTEGER offset, end; + NTSTATUS status; + afs_ccb_t *ccb; + CC_FILE_SIZES sizes, oldSizes; + ULONG towrite, ttlwritten, currpos; + LARGE_INTEGER curroff; + BOOLEAN change, paging_lock; + + ccb = IrpSp->FileObject->FsContext2; + if (IsDeviceFile(IrpSp->FileObject) || (ccb->attribs & FILE_ATTRIBUTE_DIRECTORY)) SYNC_FAIL(STATUS_INVALID_DEVICE_REQUEST); -/* since we will be performing io on this instance, start caching. */ + /* since we will be performing io on this instance, start caching. */ #ifdef EXPLICIT_CACHING -if (!IrpSp->FileObject->PrivateCacheMap) - { + if (!IrpSp->FileObject->PrivateCacheMap) + { CcInitializeCacheMap(IrpSp->FileObject, (CC_FILE_SIZES*)&fcb->AllocationSize, FALSE, &rdrExt->callbacks, IrpSp->FileObject->FsContext);//(PVOID)din->Context1); CcSetAdditionalCacheAttributes(IrpSp->FileObject, FALSE, TRUE); - } + } #endif -if (!(ccb->access & FILE_WRITE_DATA) && !(Irp->Flags & IRP_PAGING_IO)) + if (!(ccb->access & FILE_WRITE_DATA) && !(Irp->Flags & IRP_PAGING_IO)) SYNC_FAIL(STATUS_ACCESS_DENIED); -/* fast-out for zero-length i/o */ -if (!IrpSp->Parameters.Write.Length) + /* fast-out for zero-length i/o */ + if (!IrpSp->Parameters.Write.Length) SYNC_FAIL(STATUS_SUCCESS); -if (IrpSp->Parameters.Write.ByteOffset.HighPart == 0xffffffff && - IrpSp->Parameters.Write.ByteOffset.LowPart == FILE_WRITE_TO_END_OF_FILE) + if (IrpSp->Parameters.Write.ByteOffset.HighPart == 0xffffffff && + IrpSp->Parameters.Write.ByteOffset.LowPart == FILE_WRITE_TO_END_OF_FILE) offset.QuadPart = fcb->FileSize.QuadPart; -else + else offset = IrpSp->Parameters.Write.ByteOffset; -length = IrpSp->Parameters.Write.Length; + length = IrpSp->Parameters.Write.Length; -if (!(outPtr = AfsFindBuffer(Irp))) + if (!(outPtr = AfsFindBuffer(Irp))) SYNC_FAIL(STATUS_INSUFFICIENT_RESOURCES); #ifdef EXPLICIT_CACHING -if (!(Irp->Flags & (IRP_NOCACHE | IRP_PAGING_IO))) - { + if (!(Irp->Flags & (IRP_NOCACHE | IRP_PAGING_IO))) + { /* extend file for cached writes */ FsRtlEnterFileSystem(); LOCK_PAGING_FCB; if (offset.QuadPart + length > fcb->FileSize.QuadPart) - { - end.QuadPart = offset.QuadPart + length; - fcb->AllocationSize = fcb->FileSize = fcb->ValidDataLength = end; - LOCK_FCB; - CcSetFileSizes(IrpSp->FileObject, (CC_FILE_SIZES*)&fcb->AllocationSize); - UNLOCK_FCB; - /*ret = *//*CcZeroData(IrpSp->FileObject, &oldSizes.FileSize, &end, FALSE);*/ /* should wait? */ - } + { + end.QuadPart = offset.QuadPart + length; + fcb->AllocationSize = fcb->FileSize = fcb->ValidDataLength = end; + LOCK_FCB; + CcSetFileSizes(IrpSp->FileObject, (CC_FILE_SIZES*)&fcb->AllocationSize); + UNLOCK_FCB; + /*ret = *//*CcZeroData(IrpSp->FileObject, &oldSizes.FileSize, &end, FALSE);*/ /* should wait? */ + } try - { - if (!CcCopyWrite(IrpSp->FileObject, &offset, length, TRUE, outPtr)) - SYNC_FAIL(STATUS_UNSUCCESSFUL); - } + { + if (!CcCopyWrite(IrpSp->FileObject, &offset, length, TRUE, outPtr)) + SYNC_FAIL(STATUS_UNSUCCESSFUL); + } except (EXCEPTION_EXECUTE_HANDLER) - { - STATUS(STATUS_UNSUCCESSFUL, 0); - } -// KdPrint(("write %x at %x cache done\n", length, (ULONG)offset.QuadPart)); + { + STATUS(STATUS_UNSUCCESSFUL, 0); + } + // KdPrint(("write %x at %x cache done\n", length, (ULONG)offset.QuadPart)); UNLOCK_PAGING_FCB; FsRtlExitFileSystem(); ttlwritten = written = length; if (Irp->IoStatus.Status == STATUS_UNSUCCESSFUL) - SYNC_FAIL(STATUS_UNSUCCESSFUL); - } -else + SYNC_FAIL(STATUS_UNSUCCESSFUL); + } + else #endif - { + { FsRtlEnterFileSystem(); while (1) - { - if (offset.QuadPart + length > fcb->FileSize.QuadPart) - change = 1; - else - change = 0; - if (change && !(Irp->Flags & IRP_PAGING_IO)) - paging_lock = 1; - else - paging_lock = 0; - if (paging_lock) - LOCK_PAGING_FCB; - LOCK_FCB; - if (offset.QuadPart + length > fcb->FileSize.QuadPart) - { - if (Irp->Flags & IRP_PAGING_IO) - { - /* the input buffer and length is for a full page. ignore this. */ - if (offset.QuadPart > fcb->FileSize.QuadPart) - { - if (paging_lock) - { - _asm int 3; - UNLOCK_PAGING_FCB; - } - UNLOCK_FCB; - FsRtlExitFileSystem(); - SYNC_FAIL2(STATUS_SUCCESS, length); - } - length = (ULONG)(fcb->FileSize.QuadPart - offset.QuadPart); - if (paging_lock) - { - _asm int 3; - UNLOCK_PAGING_FCB; - } - break; - } - else - { - if (!change) - { - if (paging_lock) - { - _asm int 3; - UNLOCK_PAGING_FCB; - } - UNLOCK_FCB; - continue; - } - end.QuadPart = offset.QuadPart + length; - fcb->AllocationSize = fcb->FileSize = fcb->ValidDataLength = end; - CcSetFileSizes(IrpSp->FileObject, (CC_FILE_SIZES*)&fcb->AllocationSize); - if (paging_lock) - UNLOCK_PAGING_FCB; - break; - } - } - else - { - //UNLOCK_FCB; - if (paging_lock) - UNLOCK_PAGING_FCB; - break; - } - } + { + if (offset.QuadPart + length > fcb->FileSize.QuadPart) + change = 1; + else + change = 0; + if (change && !(Irp->Flags & IRP_PAGING_IO)) + paging_lock = 1; + else + paging_lock = 0; + if (paging_lock) + LOCK_PAGING_FCB; + LOCK_FCB; + if (offset.QuadPart + length > fcb->FileSize.QuadPart) + { + if (Irp->Flags & IRP_PAGING_IO) + { + /* the input buffer and length is for a full page. ignore this. */ + if (offset.QuadPart > fcb->FileSize.QuadPart) + { + if (paging_lock) + { + _asm int 3; + UNLOCK_PAGING_FCB; + } + UNLOCK_FCB; + FsRtlExitFileSystem(); + SYNC_FAIL2(STATUS_SUCCESS, length); + } + length = (ULONG)(fcb->FileSize.QuadPart - offset.QuadPart); + if (paging_lock) + { + _asm int 3; + UNLOCK_PAGING_FCB; + } + break; + } + else + { + if (!change) + { + if (paging_lock) + { + _asm int 3; + UNLOCK_PAGING_FCB; + } + UNLOCK_FCB; + continue; + } + end.QuadPart = offset.QuadPart + length; + fcb->AllocationSize = fcb->FileSize = fcb->ValidDataLength = end; + CcSetFileSizes(IrpSp->FileObject, (CC_FILE_SIZES*)&fcb->AllocationSize); + if (paging_lock) + UNLOCK_PAGING_FCB; + break; + } + } + else + { + //UNLOCK_FCB; + if (paging_lock) + UNLOCK_PAGING_FCB; + break; + } + } for (currpos = ttlwritten = 0; ttlwritten < length; ) - { - towrite = length - currpos; - towrite = (towrite > TRANSFER_CHUNK_SIZE) ? TRANSFER_CHUNK_SIZE : towrite; - curroff.QuadPart = offset.QuadPart + currpos; - status = uc_write(fcb->fid, curroff, towrite, &written, outPtr); -// KdPrint(("write %x at %x done\n", length, (ULONG)offset.QuadPart)); - if (status == 0) - { - ttlwritten += written; - currpos += written; - if (written < towrite) - goto end; - continue; - } - UNLOCK_FCB; - FsRtlExitFileSystem(); - switch (status) - { - case IFSL_RPC_TIMEOUT: SYNC_FAIL_RPC_TIMEOUT; - case IFSL_BAD_INPUT: SYNC_FAIL(STATUS_INVALID_PARAMETER); - case IFSL_OVERQUOTA: SYNC_FAIL(STATUS_DISK_FULL); - default: SYNC_FAIL(STATUS_UNSUCCESSFUL); - } - } -end: ; + { + towrite = length - currpos; + towrite = (towrite > TRANSFER_CHUNK_SIZE) ? TRANSFER_CHUNK_SIZE : towrite; + curroff.QuadPart = offset.QuadPart + currpos; + status = uc_write(fcb->fid, curroff, towrite, &written, outPtr); + // KdPrint(("write %x at %x done\n", length, (ULONG)offset.QuadPart)); + if (status == 0) + { + ttlwritten += written; + currpos += written; + if (written < towrite) + goto end; + continue; + } + UNLOCK_FCB; + FsRtlExitFileSystem(); + switch (status) + { + case IFSL_RPC_TIMEOUT: SYNC_FAIL_RPC_TIMEOUT; + case IFSL_BAD_INPUT: SYNC_FAIL(STATUS_INVALID_PARAMETER); + case IFSL_OVERQUOTA: SYNC_FAIL(STATUS_DISK_FULL); + default: SYNC_FAIL(STATUS_UNSUCCESSFUL); + } + } + end: UNLOCK_FCB; FsRtlExitFileSystem(); - } + } -if (IoIsOperationSynchronous(Irp) && !(Irp->Flags & IRP_PAGING_IO)) + if (IoIsOperationSynchronous(Irp) && !(Irp->Flags & IRP_PAGING_IO)) IrpSp->FileObject->CurrentByteOffset.QuadPart += ttlwritten; -/* if we failed a write, we would not be here. so, we must - tell the vmm that all data was written. */ -if (Irp->Flags & IRP_PAGING_IO) - SYNC_FAIL2(STATUS_SUCCESS, IrpSp->Parameters.Write.Length) -SYNC_FAIL2(STATUS_SUCCESS, ttlwritten) + /* if we failed a write, we would not be here. so, we must + * tell the vmm that all data was written. + */ + if (Irp->Flags & IRP_PAGING_IO) + SYNC_FAIL2(STATUS_SUCCESS, IrpSp->Parameters.Write.Length); + SYNC_FAIL2(STATUS_SUCCESS, ttlwritten); } -wchar_t *SEARCH_MATCH_ALL = L"**"; +static wchar_t *SEARCH_MATCH_ALL = L"**"; /********************************************************** * AfsRdrDirCtrl * - handle directory notification callbacks * - handle directory enumeration + * + * TOD: This code must performing globbing - it does not currently do so. **********************************************************/ NTSTATUS AfsRdrDirCtrl(DEVICE_OBJECT *DeviceObject, IRP *Irp, IO_STACK_LOCATION *IrpSp, afs_fcb_t *fcb) { -struct EnumDirKOut *p; -LARGE_INTEGER size, creation, access, change, written; -ULONG attribs, count; -char buf[2048]; -afs_ccb_t *ccb; -void *outPtr, *info, *pre_adj_info; -FILE_BOTH_DIR_INFORMATION *info_both, *info_both_prev; -FILE_DIRECTORY_INFORMATION *info_dir, *info_dir_prev; -FILE_NAMES_INFORMATION *info_names, *info_names_prev; -int info_size; -readdir_data_t *ii; -ULONG x, buf_size; -LARGE_INTEGER last_cookie; -BOOLEAN overflow; -NTSTATUS status; -FILE_NOTIFY_INFORMATION *notify; - -if (IsDeviceFile(IrpSp->FileObject)) + struct EnumDirKOut *p; + LARGE_INTEGER size, creation, access, change, written; + ULONG attribs, count; + char buf[2048]; + afs_ccb_t *ccb; + void *outPtr, *info, *pre_adj_info; + FILE_BOTH_DIR_INFORMATION *info_both, *info_both_prev; + FILE_DIRECTORY_INFORMATION *info_dir, *info_dir_prev; + FILE_NAMES_INFORMATION *info_names, *info_names_prev; + int info_size; + readdir_data_t *ii; + ULONG x, buf_size; + LARGE_INTEGER last_cookie; + BOOLEAN overflow; + NTSTATUS status; + FILE_NOTIFY_INFORMATION *notify; + + if (IsDeviceFile(IrpSp->FileObject)) SYNC_FAIL(STATUS_INVALID_DEVICE_REQUEST); -if (IrpSp->MinorFunction == IRP_MN_NOTIFY_CHANGE_DIRECTORY) - { + if (IrpSp->MinorFunction == IRP_MN_NOTIFY_CHANGE_DIRECTORY) + { ccb = IrpSp->FileObject->FsContext2; ccb->str.Length = wcslen(ccb->name)*sizeof(wchar_t); ccb->str.MaximumLength = ccb->str.Length + sizeof(wchar_t); @@ -1083,209 +1098,209 @@ if (IrpSp->MinorFunction == IRP_MN_NOTIFY_CHANGE_DIRECTORY) FsRtlEnterFileSystem(); LOCK_FCB; /* FIX: shared lock? */ FsRtlNotifyFullChangeDirectory(rdrExt->notifyList, &rdrExt->listHead, - ccb, - (STRING*)&ccb->str, - IrpSp->Flags & SL_WATCH_TREE, - FALSE, - /*FILE_NOTIFY_CHANGE_FILE_NAME,*/IrpSp->Parameters.NotifyDirectory.CompletionFilter, - Irp, NULL, NULL); - UNLOCK_FCB; + ccb, + (STRING*)&ccb->str, + IrpSp->Flags & SL_WATCH_TREE, + FALSE, + /*FILE_NOTIFY_CHANGE_FILE_NAME,*/IrpSp->Parameters.NotifyDirectory.CompletionFilter, + Irp, NULL, NULL); + UNLOCK_FCB; FsRtlExitFileSystem(); /* do NOT complete request; that will be done by fsrtlnotify functions */ return STATUS_PENDING; - } + } -if (IrpSp->MinorFunction != IRP_MN_QUERY_DIRECTORY) + if (IrpSp->MinorFunction != IRP_MN_QUERY_DIRECTORY) SYNC_FAIL(STATUS_NOT_IMPLEMENTED); -if (IrpSp->Parameters.QueryDirectory.FileInformationClass != FileBothDirectoryInformation && - IrpSp->Parameters.QueryDirectory.FileInformationClass != FileDirectoryInformation && - IrpSp->Parameters.QueryDirectory.FileInformationClass != FileNamesInformation) - { + if ( IrpSp->Parameters.QueryDirectory.FileInformationClass != FileBothDirectoryInformation && + IrpSp->Parameters.QueryDirectory.FileInformationClass != FileDirectoryInformation && + IrpSp->Parameters.QueryDirectory.FileInformationClass != FileNamesInformation) + { _asm int 3; rpt0(("enum", "enum class %d not supported", IrpSp->Parameters.QueryDirectory.FileInformationClass)); SYNC_FAIL(STATUS_NOT_IMPLEMENTED); - } - -ccb = IrpSp->FileObject->FsContext2; + } -if (!(outPtr = AfsFindBuffer(Irp))) + ccb = IrpSp->FileObject->FsContext2; + + if (!(outPtr = AfsFindBuffer(Irp))) SYNC_FAIL(STATUS_INSUFFICIENT_RESOURCES); -if (IrpSp->Flags & SL_INDEX_SPECIFIED) - { + if (IrpSp->Flags & SL_INDEX_SPECIFIED) + { /* we were told where to start our search; afsd should scrub this input */ ccb->cookie.QuadPart = IrpSp->Parameters.QueryDirectory.FileIndex; if (ccb->filter && ccb->filter != SEARCH_MATCH_ALL) - ExFreePoolWithTag(ccb->filter, AFS_RDR_TAG); + ExFreePoolWithTag(ccb->filter, AFS_RDR_TAG); ccb->filter = SEARCH_MATCH_ALL; - } -else if (IrpSp->Flags & SL_RESTART_SCAN || - ((IrpSp->Flags & SL_RETURN_SINGLE_ENTRY) && ccb->cookie.QuadPart == 0)) - { + } + else if (IrpSp->Flags & SL_RESTART_SCAN || + ((IrpSp->Flags & SL_RETURN_SINGLE_ENTRY) && ccb->cookie.QuadPart == 0)) + { /* copy new filter string into nonpaged memory */ ccb->cookie.QuadPart = 0; if (ccb->filter && ccb->filter != SEARCH_MATCH_ALL) - ExFreePoolWithTag(ccb->filter, AFS_RDR_TAG); + ExFreePoolWithTag(ccb->filter, AFS_RDR_TAG); buf_size = IrpSp->Parameters.QueryDirectory.FileName->Length+6; ccb->filter = ExAllocatePoolWithTag(NonPagedPool, buf_size, AFS_RDR_TAG); RtlCopyMemory(ccb->filter, IrpSp->Parameters.QueryDirectory.FileName->Buffer, buf_size); ccb->filter[IrpSp->Parameters.QueryDirectory.FileName->Length / sizeof(WCHAR)] = L'\0'; - } + } -if (IrpSp->Flags & SL_RETURN_SINGLE_ENTRY) + if (IrpSp->Flags & SL_RETURN_SINGLE_ENTRY) count = 1; -buf_size = 2040; - -status = uc_readdir(fcb->fid, ccb->cookie, ccb->filter, &count, buf, &buf_size); - -switch (status) - { - case IFSL_RPC_TIMEOUT: SYNC_FAIL_RPC_TIMEOUT; - case IFSL_BAD_INPUT: SYNC_FAIL(STATUS_INVALID_PARAMETER); - default: SYNC_FAIL(STATUS_UNSUCCESSFUL); - case 0: break; - } - -switch (IrpSp->Parameters.QueryDirectory.FileInformationClass) - { - case FileBothDirectoryInformation: - info_size = sizeof(FILE_BOTH_DIR_INFORMATION); - break; - case FileDirectoryInformation: - info_size = sizeof(FILE_DIRECTORY_INFORMATION); - break; - case FileNamesInformation: - info_size = sizeof(FILE_NAMES_INFORMATION); - break; - default: - KeBugCheckEx(0x12345, 0x98, 0x0, 0x0, 0x0); - } - -info = (FILE_BOTH_DIR_INFORMATION *)outPtr; -ii = (readdir_data_t *)buf; -Irp->IoStatus.Information = 0; -if (!count) - { + buf_size = 2040; + + status = uc_readdir(fcb->fid, ccb->cookie, ccb->filter, &count, buf, &buf_size); + + switch (status) + { + case IFSL_RPC_TIMEOUT: SYNC_FAIL_RPC_TIMEOUT; + case IFSL_BAD_INPUT: SYNC_FAIL(STATUS_INVALID_PARAMETER); + default: SYNC_FAIL(STATUS_UNSUCCESSFUL); + case 0: break; + } + + switch (IrpSp->Parameters.QueryDirectory.FileInformationClass) + { + case FileBothDirectoryInformation: + info_size = sizeof(FILE_BOTH_DIR_INFORMATION); + break; + case FileDirectoryInformation: + info_size = sizeof(FILE_DIRECTORY_INFORMATION); + break; + case FileNamesInformation: + info_size = sizeof(FILE_NAMES_INFORMATION); + break; + default: + KeBugCheckEx(0x12345, 0x98, 0x0, 0x0, 0x0); + } + + info = (FILE_BOTH_DIR_INFORMATION *)outPtr; + ii = (readdir_data_t *)buf; + Irp->IoStatus.Information = 0; + if (!count) + { if (IrpSp->Flags & SL_RETURN_SINGLE_ENTRY && ccb->cookie.QuadPart == 0) - SYNC_FAIL(STATUS_NO_SUCH_FILE); + SYNC_FAIL(STATUS_NO_SUCH_FILE); SYNC_FAIL(STATUS_NO_MORE_FILES); - } + } -info_both_prev = NULL; -info_dir_prev = NULL; -info_names_prev = NULL; -if (IrpSp->Flags & SL_RETURN_SINGLE_ENTRY) - count = 1; + info_both_prev = NULL; + info_dir_prev = NULL; + info_names_prev = NULL; + if (IrpSp->Flags & SL_RETURN_SINGLE_ENTRY) + count = 1; -for (x = 0; x < count; x++) - { + for (x = 0; x < count; x++) + { pre_adj_info = info; /* must explicitly align second and subsequent entries on 8-byte boundaries */ if (((ULONG)info & 0x7) && x) - info = (void*)(((ULONG)info) + (8-((ULONG)info & 0x7))); + info = (void*)(((ULONG)info) + (8-((ULONG)info & 0x7))); overflow = ((long)info + info_size + (long)ii->name_length > - (long)outPtr + (long)IrpSp->Parameters.QueryDirectory.Length); + (long)outPtr + (long)IrpSp->Parameters.QueryDirectory.Length); if (overflow && x != 0) - { - ccb->cookie = ii->cookie; - SYNC_FAIL2(STATUS_SUCCESS, (long)pre_adj_info - (long)outPtr); - } + { + ccb->cookie = ii->cookie; + SYNC_FAIL2(STATUS_SUCCESS, (long)pre_adj_info - (long)outPtr); + } memset(info, 0, info_size); switch (IrpSp->Parameters.QueryDirectory.FileInformationClass) - { - case FileBothDirectoryInformation: - info_both = info; - if (info_both_prev) - info_both_prev->NextEntryOffset = (char*)info_both - (char*)info_both_prev; - - info_both->NextEntryOffset = 0; - info_both->FileIndex = (ULONG)ii->cookie.QuadPart; - info_both->CreationTime.QuadPart = AfsTimeToWindowsTime(ii->creation.QuadPart); - info_both->LastAccessTime.QuadPart = AfsTimeToWindowsTime(ii->access.QuadPart); - info_both->LastWriteTime.QuadPart = AfsTimeToWindowsTime(ii->write.QuadPart); - info_both->ChangeTime.QuadPart = AfsTimeToWindowsTime(ii->change.QuadPart); - info_both->EndOfFile = info_both->AllocationSize = ii->size; - info_both->FileAttributes = ii->attribs;/*| FILE_ATTRIBUTE_READONLY*/; - info_both->EaSize = 0; - info_both->ShortNameLength = ii->short_name_length; - info_both->FileNameLength = ii->name_length; - RtlCopyMemory(info_both->ShortName, ii->short_name, ii->short_name_length*sizeof(WCHAR)); - - if (overflow) - { - Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW; - info_both->FileNameLength = 0; - info_both->FileName[0] = L'\0'; - goto done; - } - - RtlCopyMemory(info_both->FileName, ii->name, ii->name_length*sizeof(WCHAR)); - info_both_prev = info_both; - break; - - case FileDirectoryInformation: - info_dir = info; - if (info_dir_prev) - info_dir_prev->NextEntryOffset = (char*)info_dir - (char*)info_dir_prev; - - info_dir->NextEntryOffset = 0; - info_dir->FileIndex = (ULONG)ii->cookie.QuadPart; - info_dir->CreationTime.QuadPart = AfsTimeToWindowsTime(ii->creation.QuadPart); - info_dir->LastAccessTime.QuadPart = AfsTimeToWindowsTime(ii->access.QuadPart); - info_dir->LastWriteTime.QuadPart = AfsTimeToWindowsTime(ii->write.QuadPart); - info_dir->ChangeTime.QuadPart = AfsTimeToWindowsTime(ii->change.QuadPart); - info_dir->EndOfFile = info_dir->AllocationSize = ii->size; - info_dir->FileAttributes = ii->attribs /*| FILE_ATTRIBUTE_READONLY*/; - info_dir->FileNameLength = ii->name_length; - - if (overflow) - { - Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW; - info_dir->FileNameLength = 0; - info_dir->FileName[0] = L'\0'; - goto done; - } - - RtlCopyMemory(info_dir->FileName, ii->name, ii->name_length*sizeof(WCHAR)); - info_dir_prev = info_dir; - break; - - case FileNamesInformation: - info_names = info; - if (info_names_prev) - info_names_prev->NextEntryOffset = (char*)info_names - (char*)info_names_prev; - - info_names->NextEntryOffset = 0; - info_names->FileIndex = (ULONG)ii->cookie.QuadPart; - info_names->FileNameLength = ii->name_length; - - if (overflow) - { - Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW; - info_names->FileNameLength = 0; - info_names->FileName[0] = L'\0'; - goto done; - } - - RtlCopyMemory(info_names->FileName, ii->name, ii->name_length*sizeof(WCHAR)); - info_names_prev = info_names; - break; - } + { + case FileBothDirectoryInformation: + info_both = info; + if (info_both_prev) + info_both_prev->NextEntryOffset = (char*)info_both - (char*)info_both_prev; + + info_both->NextEntryOffset = 0; + info_both->FileIndex = (ULONG)ii->cookie.QuadPart; + info_both->CreationTime.QuadPart = AfsTimeToWindowsTime(ii->creation.QuadPart); + info_both->LastAccessTime.QuadPart = AfsTimeToWindowsTime(ii->access.QuadPart); + info_both->LastWriteTime.QuadPart = AfsTimeToWindowsTime(ii->write.QuadPart); + info_both->ChangeTime.QuadPart = AfsTimeToWindowsTime(ii->change.QuadPart); + info_both->EndOfFile = info_both->AllocationSize = ii->size; + info_both->FileAttributes = ii->attribs;/*| FILE_ATTRIBUTE_READONLY*/; + info_both->EaSize = 0; + info_both->ShortNameLength = ii->short_name_length; + info_both->FileNameLength = ii->name_length; + RtlCopyMemory(info_both->ShortName, ii->short_name, ii->short_name_length*sizeof(WCHAR)); + + if (overflow) + { + Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW; + info_both->FileNameLength = 0; + info_both->FileName[0] = L'\0'; + goto done; + } + + RtlCopyMemory(info_both->FileName, ii->name, ii->name_length*sizeof(WCHAR)); + info_both_prev = info_both; + break; + + case FileDirectoryInformation: + info_dir = info; + if (info_dir_prev) + info_dir_prev->NextEntryOffset = (char*)info_dir - (char*)info_dir_prev; + + info_dir->NextEntryOffset = 0; + info_dir->FileIndex = (ULONG)ii->cookie.QuadPart; + info_dir->CreationTime.QuadPart = AfsTimeToWindowsTime(ii->creation.QuadPart); + info_dir->LastAccessTime.QuadPart = AfsTimeToWindowsTime(ii->access.QuadPart); + info_dir->LastWriteTime.QuadPart = AfsTimeToWindowsTime(ii->write.QuadPart); + info_dir->ChangeTime.QuadPart = AfsTimeToWindowsTime(ii->change.QuadPart); + info_dir->EndOfFile = info_dir->AllocationSize = ii->size; + info_dir->FileAttributes = ii->attribs /*| FILE_ATTRIBUTE_READONLY*/; + info_dir->FileNameLength = ii->name_length; + + if (overflow) + { + Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW; + info_dir->FileNameLength = 0; + info_dir->FileName[0] = L'\0'; + goto done; + } + + RtlCopyMemory(info_dir->FileName, ii->name, ii->name_length*sizeof(WCHAR)); + info_dir_prev = info_dir; + break; + + case FileNamesInformation: + info_names = info; + if (info_names_prev) + info_names_prev->NextEntryOffset = (char*)info_names - (char*)info_names_prev; + + info_names->NextEntryOffset = 0; + info_names->FileIndex = (ULONG)ii->cookie.QuadPart; + info_names->FileNameLength = ii->name_length; + + if (overflow) + { + Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW; + info_names->FileNameLength = 0; + info_names->FileName[0] = L'\0'; + goto done; + } + + RtlCopyMemory(info_names->FileName, ii->name, ii->name_length*sizeof(WCHAR)); + info_names_prev = info_names; + break; + } info = (void*)(((ULONG)info) + info_size + (ULONG)ii->name_length*sizeof(WCHAR)); ii = (readdir_data_t *)(((unsigned char *)ii) + sizeof(readdir_data_t) + ii->name_length); last_cookie = ii->cookie; - } + } -Irp->IoStatus.Status = STATUS_SUCCESS; -done: - ccb->cookie = last_cookie; + Irp->IoStatus.Status = STATUS_SUCCESS; + done: + ccb->cookie = last_cookie; -SYNC_FAIL2(Irp->IoStatus.Status, (long)info - (long)outPtr); + SYNC_FAIL2(Irp->IoStatus.Status, (long)info - (long)outPtr); } @@ -1297,73 +1312,73 @@ SYNC_FAIL2(Irp->IoStatus.Status, (long)info - (long)outPtr); **********************************************************/ NTSTATUS AfsRdrQueryInfo(DEVICE_OBJECT *DeviceObject, IRP *Irp, IO_STACK_LOCATION *IrpSp, afs_fcb_t *fcb) { -FILE_BASIC_INFORMATION *infoBasic; -FILE_NAME_INFORMATION *infoName; -FILE_STANDARD_INFORMATION *infoStandard; -FILE_POSITION_INFORMATION *infoPosition; -FILE_ALL_INFORMATION *infoAll; -FILE_INTERNAL_INFORMATION *infoInternal; -LARGE_INTEGER size, creation, access, change, written; -ULONG attribs; -long count; -afs_ccb_t *ccb; -char *outPtr; -NTSTATUS status; -wchar_t *start; - -if (IsDeviceFile(IrpSp->FileObject)) + FILE_BASIC_INFORMATION *infoBasic; + FILE_NAME_INFORMATION *infoName; + FILE_STANDARD_INFORMATION *infoStandard; + FILE_POSITION_INFORMATION *infoPosition; + FILE_ALL_INFORMATION *infoAll; + FILE_INTERNAL_INFORMATION *infoInternal; + LARGE_INTEGER size, creation, access, change, written; + ULONG attribs; + long count; + afs_ccb_t *ccb; + char *outPtr; + NTSTATUS status; + wchar_t *start; + + if (IsDeviceFile(IrpSp->FileObject)) SYNC_FAIL(STATUS_UNSUCCESSFUL); // what should happen? -if (!(outPtr = AfsFindBuffer(Irp))) + if (!(outPtr = AfsFindBuffer(Irp))) SYNC_FAIL(STATUS_INSUFFICIENT_RESOURCES); -ccb = IrpSp->FileObject->FsContext2; + ccb = IrpSp->FileObject->FsContext2; -status = uc_stat(fcb->fid, &attribs, &size, &creation, &access, &change, &written); -switch (status) - { - case IFSL_RPC_TIMEOUT: SYNC_FAIL_RPC_TIMEOUT; - case IFSL_BAD_INPUT: SYNC_FAIL(STATUS_INVALID_PARAMETER); - default: SYNC_FAIL(STATUS_UNSUCCESSFUL); - case 0: break; - } + status = uc_stat(fcb->fid, &attribs, &size, &creation, &access, &change, &written); + switch (status) + { + case IFSL_RPC_TIMEOUT: SYNC_FAIL_RPC_TIMEOUT; + case IFSL_BAD_INPUT: SYNC_FAIL(STATUS_INVALID_PARAMETER); + default: SYNC_FAIL(STATUS_UNSUCCESSFUL); + case 0: break; + } -/* afsd does not maintain instance-specific data, so we adjust here */ -if (ccb->access & FILE_READ_DATA && !(ccb->access & FILE_WRITE_DATA)) + /* afsd does not maintain instance-specific data, so we adjust here */ + if (ccb->access & FILE_READ_DATA && !(ccb->access & FILE_WRITE_DATA)) attribs |= FILE_ATTRIBUTE_READONLY; -(void*)infoBasic = (void*)infoName = (void*)infoPosition = (void*)infoStandard = (void*)infoInternal = NULL; -switch (IrpSp->Parameters.QueryFile.FileInformationClass) - { - case FileBasicInformation: - infoBasic = (FILE_BASIC_INFORMATION*)outPtr; - break; - case FileNameInformation: - infoName = (FILE_NAME_INFORMATION*)outPtr; - break; - case FileStandardInformation: - infoStandard = (FILE_STANDARD_INFORMATION*)outPtr; - break; - case FilePositionInformation: - infoPosition = (FILE_POSITION_INFORMATION*)outPtr; - break; - case FileAllInformation: - infoAll = (FILE_ALL_INFORMATION*)outPtr; - infoBasic = &infoAll->BasicInformation; - infoName = &infoAll->NameInformation; - infoStandard = &infoAll->StandardInformation; - infoPosition = &infoAll->PositionInformation; - break; - case FileInternalInformation: - infoInternal = (FILE_INTERNAL_INFORMATION*)outPtr; - break; - default: - STATUS(STATUS_NOT_IMPLEMENTED, 0); - break; - } - -if (infoBasic) - { + (void*)infoBasic = (void*)infoName = (void*)infoPosition = (void*)infoStandard = (void*)infoInternal = NULL; + switch (IrpSp->Parameters.QueryFile.FileInformationClass) + { + case FileBasicInformation: + infoBasic = (FILE_BASIC_INFORMATION*)outPtr; + break; + case FileNameInformation: + infoName = (FILE_NAME_INFORMATION*)outPtr; + break; + case FileStandardInformation: + infoStandard = (FILE_STANDARD_INFORMATION*)outPtr; + break; + case FilePositionInformation: + infoPosition = (FILE_POSITION_INFORMATION*)outPtr; + break; + case FileAllInformation: + infoAll = (FILE_ALL_INFORMATION*)outPtr; + infoBasic = &infoAll->BasicInformation; + infoName = &infoAll->NameInformation; + infoStandard = &infoAll->StandardInformation; + infoPosition = &infoAll->PositionInformation; + break; + case FileInternalInformation: + infoInternal = (FILE_INTERNAL_INFORMATION*)outPtr; + break; + default: + STATUS(STATUS_NOT_IMPLEMENTED, 0); + break; + } + + if (infoBasic) + { memset(infoBasic, 0, sizeof(FILE_BASIC_INFORMATION)); infoBasic->FileAttributes = attribs; infoBasic->CreationTime.QuadPart = AfsTimeToWindowsTime(creation.QuadPart); @@ -1372,41 +1387,41 @@ if (infoBasic) infoBasic->ChangeTime.QuadPart = AfsTimeToWindowsTime(change.QuadPart); STATUS(STATUS_SUCCESS, sizeof(FILE_BASIC_INFORMATION)); //KdPrint(("query basicinfo %d,%d %x,%I64d,%I64d\n", fcb->fid, (ULONG)IrpSp->FileObject->FsContext2, infoBasic->FileAttributes, infoBasic->CreationTime.QuadPart, infoBasic->ChangeTime.QuadPart)); - } + } -if (infoName) - { + if (infoName) + { memset(infoName, 0, sizeof(FILE_NAME_INFORMATION)); start = ccb->name; count = (long)(*(start+1) - L'0'); if (count > 9 || count < 0) - SYNC_FAIL(STATUS_OBJECT_NAME_INVALID); + SYNC_FAIL(STATUS_OBJECT_NAME_INVALID); if (count || *start == L'0') - { - for ( ; count >= 0 && start; count--) - start = wcschr(start+1, L'\\'); - if (!start) - SYNC_FAIL(STATUS_OBJECT_NAME_INVALID); - } + { + for ( ; count >= 0 && start; count--) + start = wcschr(start+1, L'\\'); + if (!start) + SYNC_FAIL(STATUS_OBJECT_NAME_INVALID); + } infoName->FileNameLength = wcslen(start)*sizeof(WCHAR); if (((IrpSp->Parameters.QueryFile.FileInformationClass == FileAllInformation) ? sizeof(*infoAll) : sizeof(*infoName)) + - infoName->FileNameLength > IrpSp->Parameters.QueryFile.Length) - { - infoName->FileNameLength = 0; - infoName->FileName[0] = L'\0'; - STATUS(STATUS_BUFFER_OVERFLOW, sizeof(FILE_NAME_INFORMATION)); - //KdPrint(("query overflowing buffer %d\n", IrpSp->Parameters.QueryFile.Length)); - } + infoName->FileNameLength > IrpSp->Parameters.QueryFile.Length) + { + infoName->FileNameLength = 0; + infoName->FileName[0] = L'\0'; + STATUS(STATUS_BUFFER_OVERFLOW, sizeof(FILE_NAME_INFORMATION)); + //KdPrint(("query overflowing buffer %d\n", IrpSp->Parameters.QueryFile.Length)); + } else - { //TODO:check filename is correct/correct format - StringCbCopy(infoName->FileName, IrpSp->Parameters.QueryFile.Length - sizeof(*infoName), start); - STATUS(STATUS_SUCCESS, sizeof(FILE_NAME_INFORMATION) + (infoName->FileNameLength - sizeof(WCHAR))); - } + { //TODO:check filename is correct/correct format + StringCbCopy(infoName->FileName, IrpSp->Parameters.QueryFile.Length - sizeof(*infoName), start); + STATUS(STATUS_SUCCESS, sizeof(FILE_NAME_INFORMATION) + (infoName->FileNameLength - sizeof(WCHAR))); + } //KdPrint(("query nameinfo %ws from %ws\n", infoName->FileName, ccb->name)); - } + } -if (infoStandard) - { + if (infoStandard) + { memset(infoStandard, 0, sizeof(FILE_STANDARD_INFORMATION)); infoStandard->AllocationSize.QuadPart = size.QuadPart; infoStandard->EndOfFile.QuadPart = size.QuadPart; @@ -1417,30 +1432,30 @@ if (infoStandard) //KdPrint(("query stdinfo %d,%d %I64d,%s\n", fcb->fid, (ULONG)IrpSp->FileObject->FsContext2, infoStandard->EndOfFile.QuadPart, infoStandard->Directory?"dir":"file")); } -if (infoPosition) - { + if (infoPosition) + { infoPosition->CurrentByteOffset = IrpSp->FileObject->CurrentByteOffset; STATUS(STATUS_SUCCESS, sizeof(FILE_POSITION_INFORMATION)); //KdPrint(("query position %d,%d %I64d\n", fcb, (ULONG)IrpSp->FileObject->FsContext2, infoPosition->CurrentByteOffset.QuadPart)); - } + } -if (IrpSp->Parameters.QueryFile.FileInformationClass == FileAllInformation) - { + if (IrpSp->Parameters.QueryFile.FileInformationClass == FileAllInformation) + { if (!infoName->FileNameLength) - STATUS(STATUS_BUFFER_OVERFLOW, sizeof(FILE_ALL_INFORMATION)); - else - STATUS(STATUS_SUCCESS, sizeof(FILE_ALL_INFORMATION) + (infoName->FileNameLength - sizeof(WCHAR))); + STATUS(STATUS_BUFFER_OVERFLOW, sizeof(FILE_ALL_INFORMATION)); + else + STATUS(STATUS_SUCCESS, sizeof(FILE_ALL_INFORMATION) + (infoName->FileNameLength - sizeof(WCHAR))); } -if (infoInternal) - { + if (infoInternal) + { infoInternal->IndexNumber.QuadPart = fcb->fid; STATUS(STATUS_SUCCESS, sizeof(FILE_INTERNAL_INFORMATION)); - } + } -status = Irp->IoStatus.Status; -COMPLETE; -return status; + status = Irp->IoStatus.Status; + COMPLETE; + return status; } @@ -1455,193 +1470,195 @@ return status; **********************************************************/ NTSTATUS AfsRdrSetInfo(DEVICE_OBJECT *DeviceObject, IRP *Irp, IO_STACK_LOCATION *IrpSp, afs_fcb_t *fcb) { -struct SetInfoKOut *p; -afs_fcb_t *fcbt; -afs_ccb_t *ccb; -FILE_DISPOSITION_INFORMATION *infoDisp; -FILE_BASIC_INFORMATION *infoBasic; -FILE_END_OF_FILE_INFORMATION *infoLength; -FILE_RENAME_INFORMATION *infoRename; -FILE_POSITION_INFORMATION *infoPosition; -NTSTATUS ret; -wchar_t *buf, *part, *ptr; -ULONG size, new_fid; -NTSTATUS status; - -if (IrpSp->FileObject->FileName.Length == 0) - SYNC_FAIL(STATUS_INVALID_DEVICE_REQUEST); - -ccb = IrpSp->FileObject->FsContext2; - -switch (IrpSp->Parameters.SetFile.FileInformationClass) - { + struct SetInfoKOut *p; + afs_fcb_t *fcbt; + afs_ccb_t *ccb; + FILE_DISPOSITION_INFORMATION *infoDisp; + FILE_BASIC_INFORMATION *infoBasic; + FILE_END_OF_FILE_INFORMATION *infoLength; + FILE_RENAME_INFORMATION *infoRename; + FILE_POSITION_INFORMATION *infoPosition; + NTSTATUS ret; + wchar_t *buf, *part, *ptr; + ULONG size, new_fid; + NTSTATUS status; + + if ( IrpSp->FileObject->FileName.Length == 0) + SYNC_FAIL(STATUS_INVALID_DEVICE_REQUEST); + + ccb = IrpSp->FileObject->FsContext2; + + switch (IrpSp->Parameters.SetFile.FileInformationClass) + { /* delete disposition */ - case FileDispositionInformation: - infoDisp = Irp->AssociatedIrp.SystemBuffer; + case FileDispositionInformation: + infoDisp = Irp->AssociatedIrp.SystemBuffer; - FsRtlEnterFileSystem(); - LOCK_FCB; + FsRtlEnterFileSystem(); + LOCK_FCB; - if (infoDisp->DeleteFile) - { - if (!MmFlushImageSection(&(fcb->sectionPtrs), MmFlushForDelete)) - SYNC_FAIL(STATUS_ACCESS_DENIED); + if (infoDisp->DeleteFile) + { + if (!MmFlushImageSection(&(fcb->sectionPtrs), MmFlushForDelete)) + SYNC_FAIL(STATUS_ACCESS_DENIED); fcb->delPending |= 0x1; - } - else - fcb->delPending &= ~0x1; - UNLOCK_FCB; - FsRtlExitFileSystem(); - SYNC_RET(STATUS_SUCCESS); + } + else + fcb->delPending &= ~0x1; + UNLOCK_FCB; + FsRtlExitFileSystem(); + SYNC_RET(STATUS_SUCCESS); /*case FileAllocationInformation:*/ - case FileEndOfFileInformation: - /* ignore extensions caused by paging requests*/ - if (Irp->Flags & IRP_PAGING_IO) - SYNC_FAIL(STATUS_SUCCESS); - - infoLength = Irp->AssociatedIrp.SystemBuffer; - - FsRtlEnterFileSystem(); - LOCK_PAGING_FCB; - LOCK_FCB; - if (IrpSp->Parameters.SetFile.AdvanceOnly && (infoLength->EndOfFile.QuadPart > fcb->FileSize.QuadPart) || - !IrpSp->Parameters.SetFile.AdvanceOnly && (infoLength->EndOfFile.QuadPart < fcb->FileSize.QuadPart)) - { - status = uc_trunc(fcb->fid, infoLength->EndOfFile); - /* because it is not written to the server immediately, this error will not always happen */ - if (status == IFSL_OVERQUOTA) - { - UNLOCK_FCB; - UNLOCK_PAGING_FCB; - FsRtlExitFileSystem(); - SYNC_FAIL(STATUS_DISK_FULL); - } - } - fcb->FileSize = fcb->AllocationSize = fcb->ValidDataLength = infoLength->EndOfFile; - CcSetFileSizes(IrpSp->FileObject, (CC_FILE_SIZES*)&fcb->AllocationSize); - //CcPurgeCacheSection(IrpSp->FileObject->SectionObjectPointer, &fcb->AllocationSize, 0, FALSE); - UNLOCK_FCB; - UNLOCK_PAGING_FCB; - FsRtlExitFileSystem(); - SYNC_FAIL(STATUS_SUCCESS); - - case FileBasicInformation: - infoBasic = Irp->AssociatedIrp.SystemBuffer; - status = uc_setinfo(fcb->fid, infoBasic->FileAttributes, infoBasic->CreationTime, infoBasic->LastAccessTime, infoBasic->ChangeTime, infoBasic->LastWriteTime); - SYNC_FAIL(STATUS_SUCCESS); - - case FileRenameInformation: - //KdPrint(("set rename %d\n", fcb->fid)); - infoRename = Irp->AssociatedIrp.SystemBuffer; - new_fid = fcb->fid; - //rpt1(("setinfo", "rename %d,%d %d,%ws", ExtractFid(fcb), (ULONG)IrpSp->FileObject->FsContext2, infoRename->ReplaceIfExists, infoRename->FileName)); - - if (IrpSp->Parameters.SetFile.FileObject) - fcbt = FindFcb(IrpSp->Parameters.SetFile.FileObject); - - //null-terminate all strings into uc_rename? - //FIX/one rename case not working - - if (IrpSp->Parameters.SetFile.FileObject == NULL && - infoRename->RootDirectory == NULL) - { - WCHAR fname[300]; /* FIX: uc_rename needs null-terminated string */ - StringCchCopyNW(fname, 300-1, infoRename->FileName, infoRename->FileNameLength/sizeof(WCHAR)); - uc_rename(fcb->fid, ccb->name+2, NULL, fname, &new_fid); - fcb->fid = new_fid; - } - else if (IrpSp->Parameters.SetFile.FileObject != NULL && - infoRename->RootDirectory == NULL) - { - WCHAR fname[300]; - StringCchCopyNW(fname, 300-1, infoRename->FileName, infoRename->FileNameLength/sizeof(WCHAR)); - uc_rename(fcb->fid, ccb->name+2, fcbt->ccb_list->name+2, fname, &new_fid); - fcb->fid = new_fid; - } - else - { - _asm int 3; - /*fcbt = FindFcb(IrpSp->Parameters.SetFile.FileObject); - - p->CurrNameOff = 0; - StringCbCopyW(buf, size, fcb->name); - p->NewNameOff = wcslen(buf)+1; - StringCbCopyNW(buf + p->NewNameOff, - size - p->NewNameOff, - infoRename->FileName, - infoRename->FileNameLength*sizeof(wchar_t)); - buf[p->NewNameOff+infoRename->FileNameLength] = L'\0'; - p->NewDirOff = p->NewNameOff + wcslen(buf + p->NewNameOff)+1; - StringCbCopyW(buf + p->NewDirOff, - size - p->NewDirOff, - fcbt->name);*/ - } - SYNC_RET(STATUS_SUCCESS); - break; - - case FilePositionInformation: - infoPosition = Irp->AssociatedIrp.SystemBuffer; - IrpSp->FileObject->CurrentByteOffset = infoPosition->CurrentByteOffset; - SYNC_FAIL(STATUS_SUCCESS); - - default: - KdPrint(("set unsupp %d type %d\n", fcb->fid, IrpSp->Parameters.SetFile.FileInformationClass)); - SYNC_FAIL(STATUS_NOT_IMPLEMENTED); - } - -SYNC_FAIL(STATUS_UNSUCCESSFUL); -} + case FileEndOfFileInformation: + /* ignore extensions caused by paging requests*/ + if (Irp->Flags & IRP_PAGING_IO) + SYNC_FAIL(STATUS_SUCCESS); + + infoLength = Irp->AssociatedIrp.SystemBuffer; + + FsRtlEnterFileSystem(); + LOCK_PAGING_FCB; + LOCK_FCB; + if (IrpSp->Parameters.SetFile.AdvanceOnly && (infoLength->EndOfFile.QuadPart > fcb->FileSize.QuadPart) || + !IrpSp->Parameters.SetFile.AdvanceOnly && (infoLength->EndOfFile.QuadPart < fcb->FileSize.QuadPart)) + { + status = uc_trunc(fcb->fid, infoLength->EndOfFile); + /* because it is not written to the server immediately, this error will not always happen */ + if (status == IFSL_OVERQUOTA) + { + UNLOCK_FCB; + UNLOCK_PAGING_FCB; + FsRtlExitFileSystem(); + SYNC_FAIL(STATUS_DISK_FULL); + } + } + fcb->FileSize = fcb->AllocationSize = fcb->ValidDataLength = infoLength->EndOfFile; + CcSetFileSizes(IrpSp->FileObject, (CC_FILE_SIZES*)&fcb->AllocationSize); + //CcPurgeCacheSection(IrpSp->FileObject->SectionObjectPointer, &fcb->AllocationSize, 0, FALSE); + UNLOCK_FCB; + UNLOCK_PAGING_FCB; + FsRtlExitFileSystem(); + SYNC_FAIL(STATUS_SUCCESS); + + case FileBasicInformation: + infoBasic = Irp->AssociatedIrp.SystemBuffer; + status = uc_setinfo(fcb->fid, infoBasic->FileAttributes, infoBasic->CreationTime, infoBasic->LastAccessTime, infoBasic->ChangeTime, infoBasic->LastWriteTime); + SYNC_FAIL(STATUS_SUCCESS); + + case FileRenameInformation: + //KdPrint(("set rename %d\n", fcb->fid)); + infoRename = Irp->AssociatedIrp.SystemBuffer; + new_fid = fcb->fid; + //rpt1(("setinfo", "rename %d,%d %d,%ws", ExtractFid(fcb), (ULONG)IrpSp->FileObject->FsContext2, infoRename->ReplaceIfExists, infoRename->FileName)); + + if (IrpSp->Parameters.SetFile.FileObject) + fcbt = FindFcb(IrpSp->Parameters.SetFile.FileObject); + + //null-terminate all strings into uc_rename? + //FIX/one rename case not working + + if (IrpSp->Parameters.SetFile.FileObject == NULL && + infoRename->RootDirectory == NULL) + { + WCHAR fname[300]; /* FIX: uc_rename needs null-terminated string */ + StringCchCopyNW(fname, 300-1, infoRename->FileName, infoRename->FileNameLength/sizeof(WCHAR)); + uc_rename(fcb->fid, ccb->name+2, NULL, fname, &new_fid); + fcb->fid = new_fid; + } + else if (IrpSp->Parameters.SetFile.FileObject != NULL && + infoRename->RootDirectory == NULL) + { + WCHAR fname[300]; + StringCchCopyNW(fname, 300-1, infoRename->FileName, infoRename->FileNameLength/sizeof(WCHAR)); + uc_rename(fcb->fid, ccb->name+2, fcbt->ccb_list->name+2, fname, &new_fid); + fcb->fid = new_fid; + } + else + { + _asm int 3; + /*fcbt = FindFcb(IrpSp->Parameters.SetFile.FileObject); + + p->CurrNameOff = 0; + StringCbCopyW(buf, size, fcb->name); + p->NewNameOff = wcslen(buf)+1; + StringCbCopyNW(buf + p->NewNameOff, + size - p->NewNameOff, + infoRename->FileName, + infoRename->FileNameLength*sizeof(wchar_t)); + buf[p->NewNameOff+infoRename->FileNameLength] = L'\0'; + p->NewDirOff = p->NewNameOff + wcslen(buf + p->NewNameOff)+1; + StringCbCopyW(buf + p->NewDirOff, + size - p->NewDirOff, + fcbt->name);*/ + } + SYNC_RET(STATUS_SUCCESS); + break; + + case FilePositionInformation: + infoPosition = Irp->AssociatedIrp.SystemBuffer; + IrpSp->FileObject->CurrentByteOffset = infoPosition->CurrentByteOffset; + SYNC_FAIL(STATUS_SUCCESS); + + default: + KdPrint(("set unsupp %d type %d\n", fcb->fid, IrpSp->Parameters.SetFile.FileInformationClass)); + SYNC_FAIL(STATUS_NOT_IMPLEMENTED); + } + + SYNC_FAIL(STATUS_UNSUCCESSFUL); +} dc_break_callback(ULONG fid) { -afs_fcb_t *fcb; -int pos; -USHORT len; -UNICODE_STRING *s; - -LOCK_FCB_LIST; - -fcb = find_fcb(fid); -if (!fcb) - { + afs_fcb_t *fcb; + int pos; + USHORT len; + UNICODE_STRING *s; + + LOCK_FCB_LIST; + + fcb = find_fcb(fid); + if (!fcb) + { UNLOCK_FCB_LIST; return 1; /* we are done with this file */ - } - -ASSERT(fcb->ccb_list); -/*pos = wcslen(fcb->ccb_list->name); -if (fcb->ccb_list->name[pos-1] == L'\\') - pos--; -ASSERT(pos); -while (pos > 0) - { - if (fcb->ccb_list->name[pos-1] == L'\\') - break; - pos--; - }*/ - -len = (wcslen(fcb->ccb_list->name) + 10) * sizeof(wchar_t); -s = ExAllocatePool(NonPagedPool, sizeof(UNICODE_STRING)+len+sizeof(wchar_t)); -s->Length = len; -s->MaximumLength = len + sizeof(wchar_t); -s->Buffer = (PWSTR)(s+1); - -StringCbCopyW((PWSTR)(s+1), len, fcb->ccb_list->name); -if (s->Buffer[wcslen(s->Buffer) - 1] != L'\\') + } + + ASSERT(fcb->ccb_list); +#if 0 + pos = wcslen(fcb->ccb_list->name); + if (fcb->ccb_list->name[pos-1] == L'\\') + pos--; + ASSERT(pos); + while (pos > 0) + { + if (fcb->ccb_list->name[pos-1] == L'\\') + break; + pos--; + } + #endif /* 0 */ + + len = (wcslen(fcb->ccb_list->name) + 10) * sizeof(wchar_t); + s = ExAllocatePool(NonPagedPool, sizeof(UNICODE_STRING)+len+sizeof(wchar_t)); + s->Length = len; + s->MaximumLength = len + sizeof(wchar_t); + s->Buffer = (PWSTR)(s+1); + + StringCbCopyW((PWSTR)(s+1), len, fcb->ccb_list->name); + if (s->Buffer[wcslen(s->Buffer) - 1] != L'\\') StringCbCatW(s->Buffer, len, L"\\"); -pos = wcslen(s->Buffer); -StringCbCatW(s->Buffer, len, L"jj"); /* FIX: make bogus change notification */ + pos = wcslen(s->Buffer); + StringCbCatW(s->Buffer, len, L"jj"); /* FIX: make bogus change notification */ -KdPrint(("break callback on %d %ws %ws\n", fid, fcb->ccb_list->name, fcb->ccb_list->name+pos)); + KdPrint(("break callback on %d %ws %ws\n", fid, fcb->ccb_list->name, fcb->ccb_list->name+pos)); -FsRtlNotifyFullReportChange(rdrExt->notifyList, &rdrExt->listHead, - (PSTRING)s, (USHORT)pos*sizeof(wchar_t), NULL, NULL, - FILE_NOTIFY_CHANGE_FILE_NAME/*FILE_NOTIFY_VALID_MASK/*FILE_NOTIFY_CHANGE_FILE_NAME*/, FILE_ACTION_ADDED, NULL); + FsRtlNotifyFullReportChange(rdrExt->notifyList, &rdrExt->listHead, + (PSTRING)s, (USHORT)pos*sizeof(wchar_t), NULL, NULL, + FILE_NOTIFY_CHANGE_FILE_NAME/*FILE_NOTIFY_VALID_MASK/*FILE_NOTIFY_CHANGE_FILE_NAME*/, FILE_ACTION_ADDED, NULL); -ExFreePool(s); -UNLOCK_FCB_LIST; -return 0; + ExFreePool(s); + UNLOCK_FCB_LIST; + return 0; } /********************************************************** @@ -1651,88 +1668,88 @@ return 0; **********************************************************/ NTSTATUS AfsRdrDeviceControl(DEVICE_OBJECT *DeviceObject, IRP *Irp, IO_STACK_LOCATION *IrpSp, afs_fcb_t *fcb) { -struct KOutEntry *entry; -NTSTATUS ret; -struct CbKIn *kin; -USHORT offset; -UNICODE_STRING nm; -void *outPtr; -ULONG key, code, length; - -/* utility ioctls */ -if (DeviceObject == ComDevice && - IrpSp->FileObject->FsContext2 == COMM_IOCTL && - IrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_AFSRDR_IOCTL) - { + struct KOutEntry *entry; + NTSTATUS ret; + struct CbKIn *kin; + USHORT offset; + UNICODE_STRING nm; + void *outPtr; + ULONG key, code, length; + + /* utility ioctls */ + if (DeviceObject == ComDevice && + IrpSp->FileObject->FsContext2 == COMM_IOCTL && + IrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_AFSRDR_IOCTL) + { outPtr = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority); if (!outPtr) - _asm int 3; + _asm int 3; rpc_set_context(IrpSp->FileObject->FsContext); code = uc_ioctl_write(IrpSp->Parameters.DeviceIoControl.InputBufferLength, - Irp->AssociatedIrp.SystemBuffer, - (ULONG*)&key); + Irp->AssociatedIrp.SystemBuffer, + (ULONG*)&key); length = IrpSp->Parameters.DeviceIoControl.OutputBufferLength; if (!code) - code = uc_ioctl_read(key, &length, outPtr); + code = uc_ioctl_read(key, &length, outPtr); rpc_remove_context(); switch (code) - { - case IFSL_SUCCESS: - STATUS(STATUS_SUCCESS, length); - break; - default: - STATUS(STATUS_UNSUCCESSFUL, 0); - break; - } - } -/* downcalls by afsd */ -else if (DeviceObject == ComDevice && - IrpSp->FileObject->FsContext2 == COMM_DOWNCALL && - IrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_AFSRDR_DOWNCALL) - { + { + case IFSL_SUCCESS: + STATUS(STATUS_SUCCESS, length); + break; + default: + STATUS(STATUS_UNSUCCESSFUL, 0); + break; + } + } + /* downcalls by afsd */ + else if (DeviceObject == ComDevice && + IrpSp->FileObject->FsContext2 == COMM_DOWNCALL && + IrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_AFSRDR_DOWNCALL) + { outPtr = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority); if (!outPtr) - _asm int 3; + _asm int 3; rpc_set_context(IrpSp->FileObject->FsContext); code = rpc_call(IrpSp->Parameters.DeviceIoControl.InputBufferLength, - Irp->AssociatedIrp.SystemBuffer, - IrpSp->Parameters.DeviceIoControl.OutputBufferLength, - outPtr, - &length); + Irp->AssociatedIrp.SystemBuffer, + IrpSp->Parameters.DeviceIoControl.OutputBufferLength, + outPtr, + &length); rpc_remove_context(); switch (code) - { - case IFSL_SUCCESS: - STATUS(STATUS_SUCCESS, length); - break; - default: - STATUS(STATUS_UNSUCCESSFUL, 0); - break; - } - } -else if (DeviceObject == RdrDevice && - IrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_AFSRDR_GET_PATH) - { + { + case IFSL_SUCCESS: + STATUS(STATUS_SUCCESS, length); + break; + default: + STATUS(STATUS_UNSUCCESSFUL, 0); + break; + } + } + else if (DeviceObject == RdrDevice && + IrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_AFSRDR_GET_PATH) + { outPtr = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority); if (!outPtr) - _asm int 3; + _asm int 3; StringCbCopyW(outPtr, IrpSp->Parameters.DeviceIoControl.OutputBufferLength, fcb->ccb_list->name+2); STATUS(STATUS_SUCCESS, (wcslen(outPtr)+1)*sizeof(wchar_t)); - } -else - { + } + else + { rpt0(("devctl", "devctl %d rejected", IrpSp->Parameters.DeviceIoControl.IoControlCode)); SYNC_FAIL(STATUS_INVALID_DEVICE_REQUEST); - } + } -ret = Irp->IoStatus.Status; -COMPLETE; -return ret; + ret = Irp->IoStatus.Status; + COMPLETE; + return ret; } @@ -1743,50 +1760,54 @@ return ret; **********************************************************/ NTSTATUS AfsRdrCleanup(DEVICE_OBJECT *DeviceObject, IRP *Irp, IO_STACK_LOCATION *IrpSp, afs_fcb_t *fcb) { -NTSTATUS ret; -struct AfsRdrExtension *ext; - -//try { -IrpSp = IoGetCurrentIrpStackLocation(Irp); - -if (IrpSp->FileObject->FileName.Length == 0) - SYNC_FAIL(STATUS_SUCCESS); - -ext = ((struct AfsRdrExtension*)RdrDevice->DeviceExtension); - -LOCK_FCB_LIST; -LOCK_PAGING_FCB; -LOCK_FCB; + NTSTATUS ret; + struct AfsRdrExtension *ext; -FsRtlNotifyCleanup(ext->notifyList, &ext->listHead, IrpSp->FileObject->FsContext2); - -CcFlushCache(IrpSp->FileObject->SectionObjectPointer, NULL, 0, NULL); - -if (fcb->delPending && !MmFlushImageSection(&(fcb->sectionPtrs), MmFlushForDelete)) - /* yes, moot at this point */ - STATUS(STATUS_ACCESS_DENIED, 0); -else - STATUS(STATUS_SUCCESS, 0); - -MmFlushImageSection(IrpSp->FileObject->SectionObjectPointer, MmFlushForWrite); -CcPurgeCacheSection(IrpSp->FileObject->SectionObjectPointer, NULL, 0, TRUE); -CcUninitializeCacheMap(IrpSp->FileObject, NULL, NULL); - -UNLOCK_FCB; -UNLOCK_PAGING_FCB; -UNLOCK_FCB_LIST; - -/*} except(EXCEPTION_EXECUTE_HANDLER) - { +#if 0 + try { +#endif + IrpSp = IoGetCurrentIrpStackLocation(Irp); + + if (IrpSp->FileObject->FileName.Length == 0) + SYNC_FAIL(STATUS_SUCCESS); + + ext = ((struct AfsRdrExtension*)RdrDevice->DeviceExtension); + + LOCK_FCB_LIST; + LOCK_PAGING_FCB; + LOCK_FCB; + + FsRtlNotifyCleanup(ext->notifyList, &ext->listHead, IrpSp->FileObject->FsContext2); + + CcFlushCache(IrpSp->FileObject->SectionObjectPointer, NULL, 0, NULL); + + if (fcb->delPending && !MmFlushImageSection(&(fcb->sectionPtrs), MmFlushForDelete)) + /* yes, moot at this point */ + STATUS(STATUS_ACCESS_DENIED, 0); + else + STATUS(STATUS_SUCCESS, 0); + + MmFlushImageSection(IrpSp->FileObject->SectionObjectPointer, MmFlushForWrite); + CcPurgeCacheSection(IrpSp->FileObject->SectionObjectPointer, NULL, 0, TRUE); + CcUninitializeCacheMap(IrpSp->FileObject, NULL, NULL); + + UNLOCK_FCB; + UNLOCK_PAGING_FCB; + UNLOCK_FCB_LIST; + +#if 0 + } except(EXCEPTION_EXECUTE_HANDLER) + { _asm int 3; STATUS(STATUS_UNSUCCESSFUL, 0); ExReleaseResourceLite(&ext->fcbLock); FsRtlExitFileSystem(); - }*/ + } +#endif -ret = Irp->IoStatus.Status; -COMPLETE; -return ret; + ret = Irp->IoStatus.Status; + COMPLETE; + return ret; } @@ -1797,58 +1818,58 @@ return ret; **********************************************************/ NTSTATUS AfsRdrClose(DEVICE_OBJECT *DeviceObject, IRP *Irp, IO_STACK_LOCATION *IrpSp, afs_fcb_t *fcb) { -ULONG length; -wchar_t *name; -char kill; -KEVENT ev; -LARGE_INTEGER timeout; -afs_ccb_t *ccb, *curr; - -if (IrpSp->FileObject->FileName.Length == 0) + ULONG length; + wchar_t *name; + char kill; + KEVENT ev; + LARGE_INTEGER timeout; + afs_ccb_t *ccb, *curr; + + if (IrpSp->FileObject->FileName.Length == 0) SYNC_FAIL(STATUS_SUCCESS); -ccb = IrpSp->FileObject->FsContext2; -LOCK_FCB_LIST; + ccb = IrpSp->FileObject->FsContext2; + LOCK_FCB_LIST; -/* set share correctly so future opens can succeed */ -IoRemoveShareAccess(IrpSp->FileObject, &fcb->share_access); -ObDereferenceObject(ccb->token); + /* set share correctly so future opens can succeed */ + IoRemoveShareAccess(IrpSp->FileObject, &fcb->share_access); + ObDereferenceObject(ccb->token); -curr = fcb->ccb_list; -if (fcb->ccb_list == ccb) + curr = fcb->ccb_list; + if (fcb->ccb_list == ccb) fcb->ccb_list = fcb->ccb_list->next; -else + else while (curr->next) - { - if (curr->next == ccb) - { - curr->next = curr->next->next; - break; - } - curr = curr->next; - } - -if (!fcb->ccb_list) - { + { + if (curr->next == ccb) + { + curr->next = curr->next->next; + break; + } + curr = curr->next; + } + + if (!fcb->ccb_list) + { uc_close(fcb->fid); if (fcb->delPending) - { - uc_unlink(ccb->name+2); - } + { + uc_unlink(ccb->name+2); + } ExDeleteResourceLite(&fcb->_resource); ExDeleteResourceLite(&fcb->_pagingIoResource); RtlDeleteElementGenericTable(&rdrExt->fcbTable, &fcb); ExFreeToNPagedLookasideList(&rdrExt->fcbMemList, fcb); - } + } -ExFreePoolWithTag(ccb->name, AFS_RDR_TAG); -if (ccb->filter && ccb->filter != SEARCH_MATCH_ALL) + ExFreePoolWithTag(ccb->name, AFS_RDR_TAG); + if (ccb->filter && ccb->filter != SEARCH_MATCH_ALL) ExFreePoolWithTag(ccb->filter, AFS_RDR_TAG); -ExFreeToNPagedLookasideList(&rdrExt->ccbMemList, ccb); + ExFreeToNPagedLookasideList(&rdrExt->ccbMemList, ccb); -UNLOCK_FCB_LIST; + UNLOCK_FCB_LIST; -SYNC_FAIL(STATUS_SUCCESS); + SYNC_FAIL(STATUS_SUCCESS); } @@ -1858,9 +1879,9 @@ SYNC_FAIL(STATUS_SUCCESS); **********************************************************/ NTSTATUS AfsRdrShutdown(DEVICE_OBJECT *DeviceObject, IRP *Irp, IO_STACK_LOCATION *IrpSp) { -_asm int 3; -STATUS(STATUS_SUCCESS, 0); -COMPLETE; + _asm int 3; + STATUS(STATUS_SUCCESS, 0); + COMPLETE; } @@ -1870,24 +1891,24 @@ COMPLETE; **********************************************************/ NTSTATUS AfsRdrFlushFile(DEVICE_OBJECT *DeviceObject, IRP *Irp, IO_STACK_LOCATION *IrpSp, afs_fcb_t *fcb) { -NTSTATUS ret; -afs_ccb_t *ccb; + NTSTATUS ret; + afs_ccb_t *ccb; -/*TRY*/ -IrpSp = IoGetCurrentIrpStackLocation(Irp); + /*TRY*/ + IrpSp = IoGetCurrentIrpStackLocation(Irp); -if (IrpSp->FileObject->FileName.Length == 0) + if (IrpSp->FileObject->FileName.Length == 0) SYNC_RET(STATUS_INVALID_DEVICE_REQUEST); -ccb = IrpSp->FileObject->FsContext2; + ccb = IrpSp->FileObject->FsContext2; -CcFlushCache(&fcb->sectionPtrs, NULL, 0, &Irp->IoStatus); + CcFlushCache(&fcb->sectionPtrs, NULL, 0, &Irp->IoStatus); -//SYNC_FAIL2(/*STATUS_LOCK_NOT_GRANTED*//*STATUS_NOT_IMPLEMENTED*/STATUS_SUCCESS, 0); + //SYNC_FAIL2(/*STATUS_LOCK_NOT_GRANTED*//*STATUS_NOT_IMPLEMENTED*/STATUS_SUCCESS, 0); -/*EXCEPT(STATUS_UNSUCCESSFUL, 0);*/ -COMPLETE; -return Irp->IoStatus.Status; + /*EXCEPT(STATUS_UNSUCCESSFUL, 0);*/ + COMPLETE; + return Irp->IoStatus.Status; } @@ -1897,21 +1918,21 @@ return Irp->IoStatus.Status; **********************************************************/ NTSTATUS AfsRdrLockCtrl(DEVICE_OBJECT *DeviceObject, IRP *Irp, IO_STACK_LOCATION *IrpSp, afs_fcb_t *fcb) { -NTSTATUS ret; + NTSTATUS ret; -/*TRY*/ -IrpSp = IoGetCurrentIrpStackLocation(Irp); + /*TRY*/ + IrpSp = IoGetCurrentIrpStackLocation(Irp); -/* complete lock on control device object without processing, as directed */ -if (IrpSp->FileObject->FileName.Length == 0) - { + /* complete lock on control device object without processing, as directed */ + if (IrpSp->FileObject->FileName.Length == 0) + { rpt0(("lock", "lock granted on root device obj")); SYNC_FAIL(STATUS_SUCCESS); - } + } -SYNC_FAIL2(/*STATUS_LOCK_NOT_GRANTED*//*STATUS_NOT_IMPLEMENTED*/STATUS_SUCCESS, 0); + SYNC_FAIL2(/*STATUS_LOCK_NOT_GRANTED*//*STATUS_NOT_IMPLEMENTED*/STATUS_SUCCESS, 0); -/*EXCEPT(STATUS_UNSUCCESSFUL, 0);*/ + /*EXCEPT(STATUS_UNSUCCESSFUL, 0);*/ } @@ -1921,317 +1942,331 @@ SYNC_FAIL2(/*STATUS_LOCK_NOT_GRANTED*//*STATUS_NOT_IMPLEMENTED*/STATUS_SUCCESS, **********************************************************/ NTSTATUS AfsRdrQueryVol(DEVICE_OBJECT *DeviceObject, IRP *Irp, IO_STACK_LOCATION *IrpSp) { -FILE_FS_ATTRIBUTE_INFORMATION *infoAttr; -FILE_FS_DEVICE_INFORMATION *infoDevice; -FILE_FS_SIZE_INFORMATION * infoSize; -FILE_FS_VOLUME_INFORMATION *infoVolume; -NTSTATUS ret; + FILE_FS_ATTRIBUTE_INFORMATION *infoAttr; + FILE_FS_DEVICE_INFORMATION *infoDevice; + FILE_FS_SIZE_INFORMATION * infoSize; + FILE_FS_VOLUME_INFORMATION *infoVolume; + NTSTATUS ret; -TRY + TRY -switch (IrpSp->Parameters.QueryVolume.FsInformationClass) + switch (IrpSp->Parameters.QueryVolume.FsInformationClass) { case FileFsAttributeInformation: - infoAttr = (FILE_FS_ATTRIBUTE_INFORMATION*)Irp->AssociatedIrp.SystemBuffer; - memset(infoAttr, 0, sizeof(FILE_FS_ATTRIBUTE_INFORMATION)); - infoAttr->FileSystemAttributes = FILE_CASE_PRESERVED_NAMES | FILE_CASE_SENSITIVE_SEARCH; //TODOTODO:? - infoAttr->MaximumComponentNameLength = 255; // should this be 255? - ///RtlCopyMemory(infoAttr->FileSystemName, L"AFS", 2); - ///infoAttr->FileSystemNameLength = 2; - //StringCbCopyLen(infoAttr->FileSystemName, IrpSp->Parameters.QueryVolume.Length-sizeof(*infoAttr)-2, L"AFS", &infoAttr->FileSystemNameLength); - //IrpSp->Parameters.QueryVolume.Length = 0; - //Irp->IoStatus.Information = sizeof(*infoAttr) + (infoAttr->FileSystemNameLength - sizeof(WCHAR)); - if (sizeof(*infoAttr) + wcslen(AFS_FS_NAME)*sizeof(wchar_t) > IrpSp->Parameters.QueryVolume.Length) - { - infoAttr->FileSystemNameLength = 0; - rpt0(("vol", "overflowing attr buffer %d", IrpSp->Parameters.QueryVolume.Length)); - SYNC_FAIL2(STATUS_BUFFER_OVERFLOW, sizeof(*infoAttr)); - } - else - { - infoAttr->FileSystemNameLength = wcslen(AFS_FS_NAME)*sizeof(wchar_t); - StringCbCopyW(infoAttr->FileSystemName, IrpSp->Parameters.QueryVolume.Length - sizeof(*infoAttr) + sizeof(WCHAR), AFS_FS_NAME); - SYNC_FAIL2(STATUS_SUCCESS, sizeof(*infoAttr) + (infoAttr->FileSystemNameLength - sizeof(WCHAR))); - } - break; + infoAttr = (FILE_FS_ATTRIBUTE_INFORMATION*)Irp->AssociatedIrp.SystemBuffer; + memset(infoAttr, 0, sizeof(FILE_FS_ATTRIBUTE_INFORMATION)); + infoAttr->FileSystemAttributes = FILE_CASE_PRESERVED_NAMES | FILE_CASE_SENSITIVE_SEARCH; //TODOTODO:? + infoAttr->MaximumComponentNameLength = 255; // should this be 255? + ///RtlCopyMemory(infoAttr->FileSystemName, L"AFS", 2); + ///infoAttr->FileSystemNameLength = 2; + //StringCbCopyLen(infoAttr->FileSystemName, IrpSp->Parameters.QueryVolume.Length-sizeof(*infoAttr)-2, L"AFS", &infoAttr->FileSystemNameLength); + //IrpSp->Parameters.QueryVolume.Length = 0; + //Irp->IoStatus.Information = sizeof(*infoAttr) + (infoAttr->FileSystemNameLength - sizeof(WCHAR)); + if (sizeof(*infoAttr) + wcslen(AFS_FS_NAME)*sizeof(wchar_t) > IrpSp->Parameters.QueryVolume.Length) + { + infoAttr->FileSystemNameLength = 0; + rpt0(("vol", "overflowing attr buffer %d", IrpSp->Parameters.QueryVolume.Length)); + SYNC_FAIL2(STATUS_BUFFER_OVERFLOW, sizeof(*infoAttr)); + } + else + { + infoAttr->FileSystemNameLength = wcslen(AFS_FS_NAME)*sizeof(wchar_t); + StringCbCopyW(infoAttr->FileSystemName, IrpSp->Parameters.QueryVolume.Length - sizeof(*infoAttr) + sizeof(WCHAR), AFS_FS_NAME); + SYNC_FAIL2(STATUS_SUCCESS, sizeof(*infoAttr) + (infoAttr->FileSystemNameLength - sizeof(WCHAR))); + } + break; case FileFsDeviceInformation: - infoDevice = (FILE_FS_DEVICE_INFORMATION*)Irp->AssociatedIrp.SystemBuffer; - memset(infoDevice, 0, sizeof(FILE_FS_DEVICE_INFORMATION)); - infoDevice->DeviceType = FILE_DEVICE_DISK;//DeviceObject->DeviceType;// FILE_DEVICE_NETWORK_FILE_SYSTEM; - infoDevice->Characteristics = DeviceObject->Characteristics;//FILE_DEVICE_IS_MOUNTED /*| FILE_REMOTE_DEVICE*/; // remote device? - IrpSp->Parameters.QueryVolume.Length = sizeof(*infoDevice); - SYNC_FAIL2(STATUS_SUCCESS, IrpSp->Parameters.QueryVolume.Length); - break; + infoDevice = (FILE_FS_DEVICE_INFORMATION*)Irp->AssociatedIrp.SystemBuffer; + memset(infoDevice, 0, sizeof(FILE_FS_DEVICE_INFORMATION)); + infoDevice->DeviceType = FILE_DEVICE_DISK;//DeviceObject->DeviceType;// FILE_DEVICE_NETWORK_FILE_SYSTEM; + infoDevice->Characteristics = DeviceObject->Characteristics;//FILE_DEVICE_IS_MOUNTED /*| FILE_REMOTE_DEVICE*/; // remote device? + IrpSp->Parameters.QueryVolume.Length = sizeof(*infoDevice); + SYNC_FAIL2(STATUS_SUCCESS, IrpSp->Parameters.QueryVolume.Length); + break; case FileFsSizeInformation: - infoSize = (FILE_FS_SIZE_INFORMATION*)Irp->AssociatedIrp.SystemBuffer; - memset(infoSize, 0, sizeof(FILE_FS_SIZE_INFORMATION)); - infoSize->TotalAllocationUnits.QuadPart = 0x00000000F0000000; //FIX - infoSize->AvailableAllocationUnits.QuadPart = 0x00000000E0000000; - infoSize->SectorsPerAllocationUnit = 1; - infoSize->BytesPerSector = 1; - IrpSp->Parameters.QueryVolume.Length = sizeof(*infoSize); - SYNC_FAIL2(STATUS_SUCCESS, IrpSp->Parameters.QueryVolume.Length); - break; + infoSize = (FILE_FS_SIZE_INFORMATION*)Irp->AssociatedIrp.SystemBuffer; + memset(infoSize, 0, sizeof(FILE_FS_SIZE_INFORMATION)); + infoSize->TotalAllocationUnits.QuadPart = 0x00000000F0000000; //FIX + infoSize->AvailableAllocationUnits.QuadPart = 0x00000000E0000000; + infoSize->SectorsPerAllocationUnit = 1; + infoSize->BytesPerSector = 1; + IrpSp->Parameters.QueryVolume.Length = sizeof(*infoSize); + SYNC_FAIL2(STATUS_SUCCESS, IrpSp->Parameters.QueryVolume.Length); + break; case FileFsVolumeInformation: - infoVolume = (FILE_FS_VOLUME_INFORMATION*)Irp->AssociatedIrp.SystemBuffer; - memset(infoVolume, 0, sizeof(FILE_FS_VOLUME_INFORMATION)); - infoVolume->VolumeCreationTime.QuadPart = AfsTimeToWindowsTime(1080000000);//0x43218765); //TODO:fix - infoVolume->VolumeSerialNumber = 0x12345678; //TODO:fix - infoVolume->SupportsObjects = FALSE; - //StringCbCopyLen(infoVolume->VolumeLabel, IrpSp->Parameters.QueryVolume.Length-sizeof(*infoVolume)-2, L"AfsRed", &infoVolume->VolumeLabelLength); - //IrpSp->Parameters.QueryVolume.Length = 0; - if (sizeof(*infoVolume) + 12 > IrpSp->Parameters.QueryVolume.Length) - { - infoVolume->VolumeLabelLength = 0; - rpt0(("vol", "overflowing buffer %d", IrpSp->Parameters.QueryVolume.Length)); - SYNC_FAIL2(STATUS_BUFFER_OVERFLOW, sizeof(*infoVolume)); - } - else - { - infoVolume->VolumeLabelLength = 12; - RtlCopyMemory(infoVolume->VolumeLabel, L"AfsRed", 12); - SYNC_FAIL2(STATUS_SUCCESS, sizeof(*infoVolume) + (infoVolume->VolumeLabelLength - sizeof(WCHAR))); - } - break; + infoVolume = (FILE_FS_VOLUME_INFORMATION*)Irp->AssociatedIrp.SystemBuffer; + memset(infoVolume, 0, sizeof(FILE_FS_VOLUME_INFORMATION)); + infoVolume->VolumeCreationTime.QuadPart = AfsTimeToWindowsTime(1080000000);//0x43218765); //TODO:fix + infoVolume->VolumeSerialNumber = 0x12345678; //TODO:fix + infoVolume->SupportsObjects = FALSE; + //StringCbCopyLen(infoVolume->VolumeLabel, IrpSp->Parameters.QueryVolume.Length-sizeof(*infoVolume)-2, L"AfsRed", &infoVolume->VolumeLabelLength); + //IrpSp->Parameters.QueryVolume.Length = 0; + if (sizeof(*infoVolume) + 12 > IrpSp->Parameters.QueryVolume.Length) + { + infoVolume->VolumeLabelLength = 0; + rpt0(("vol", "overflowing buffer %d", IrpSp->Parameters.QueryVolume.Length)); + SYNC_FAIL2(STATUS_BUFFER_OVERFLOW, sizeof(*infoVolume)); + } + else + { + infoVolume->VolumeLabelLength = 12; + RtlCopyMemory(infoVolume->VolumeLabel, L"AfsRed", 12); + SYNC_FAIL2(STATUS_SUCCESS, sizeof(*infoVolume) + (infoVolume->VolumeLabelLength - sizeof(WCHAR))); + } + break; //case FileFsFullSizeInformation: - //TODO: + //TODO: } -EXCEPT(STATUS_UNSUCCESSFUL, 0); + EXCEPT(STATUS_UNSUCCESSFUL, 0); -rpt0(("vol", "vol class %d unknown", IrpSp->Parameters.QueryVolume.FsInformationClass)); -SYNC_FAIL(STATUS_NOT_IMPLEMENTED); + rpt0(("vol", "vol class %d unknown", IrpSp->Parameters.QueryVolume.FsInformationClass)); + SYNC_FAIL(STATUS_NOT_IMPLEMENTED); } VOID AfsRdrUnload(DRIVER_OBJECT *DriverObject) { -UNICODE_STRING userModeName; + UNICODE_STRING userModeName; -FsRtlNotifyUninitializeSync(&rdrExt->notifyList); + FsRtlNotifyUninitializeSync(&rdrExt->notifyList); -RtlInitUnicodeString(&userModeName, L"\\DosDevices\\afscom"); -IoDeleteSymbolicLink(&userModeName); + RtlInitUnicodeString(&userModeName, L"\\DosDevices\\afscom"); + IoDeleteSymbolicLink(&userModeName); -/*RtlInitUnicodeString(&userModeName, L"\\DosDevices\\T:"); -IoDeleteSymbolicLink(&userModeName);*/ + /*RtlInitUnicodeString(&userModeName, L"\\DosDevices\\T:"); + IoDeleteSymbolicLink(&userModeName);*/ -ExDeleteNPagedLookasideList(&rdrExt->fcbMemList); -ExDeleteNPagedLookasideList(&rdrExt->ccbMemList); + ExDeleteNPagedLookasideList(&rdrExt->fcbMemList); + ExDeleteNPagedLookasideList(&rdrExt->ccbMemList); -rpc_shutdown(); + rpc_shutdown(); -IoDeleteDevice(ComDevice); -IoDeleteDevice(RdrDevice); + IoDeleteDevice(ComDevice); + IoDeleteDevice(RdrDevice); #ifdef RPT_ENA -rptCliClose(REPORT); + rptCliClose(REPORT); #endif -KdPrint(("RdrUnload exiting.\n")); + KdPrint(("RdrUnload exiting.\n")); } // handles all non-handled irp's synchronously NTSTATUS AfsRdrNull(DEVICE_OBJECT *DeviceObject, IRP *Irp, IO_STACK_LOCATION *IrpSp) { -NTSTATUS ret; + NTSTATUS ret; -/*TRY -rpt0(("kunhand", IrpMjFuncDesc[IrpSp->MajorFunction]));*/ + /*TRY + rpt0(("kunhand", IrpMjFuncDesc[IrpSp->MajorFunction]));*/ -SYNC_FAIL(STATUS_NOT_IMPLEMENTED); + SYNC_FAIL(STATUS_NOT_IMPLEMENTED); -/*EXCEPT(STATUS_UNSUCCESSFUL, 0); + /*EXCEPT(STATUS_UNSUCCESSFUL, 0); -ret = Irp->IoStatus.Status; -COMPLETE_NO_BOOST; -return ret;*/ + ret = Irp->IoStatus.Status; + COMPLETE_NO_BOOST; + return ret;*/ } NTSTATUS ComDispatch(DEVICE_OBJECT *DeviceObject, IRP *Irp) { -IO_STACK_LOCATION *IrpSp, *IrpSpClient; -NTSTATUS ret; -struct ComExtension *ext; -void *ptr, *ptr2; -rpc_t find, *find_ptr; -LARGE_INTEGER timeout; -struct afsFcb *fcb; -rpc_t *rpc, **rpcp; -ULONG len; -ULONG code, read; -PACCESS_TOKEN acc_token; - -ext = (struct ComExtension *)DeviceObject->DeviceExtension; -IrpSp = IoGetCurrentIrpStackLocation(Irp); - -switch (IrpSp->MajorFunction) - { - case IRP_MJ_CREATE: - IrpSp->FileObject->FsContext = 0; - IrpSp->FileObject->FsContext2 = 0; - if (IrpSp->FileObject->FileName.Length) - { - /* ioctls come from fs, vos, bos, etc. using a pre-existing interface */ - /* downcalls come from afsd, using a new interface */ - /* upcall hooks come from afsd */ - if (!wcscmp(IrpSp->FileObject->FileName.Buffer, L"\\ioctl")) - IrpSp->FileObject->FsContext2 = COMM_IOCTL; - else if (!wcscmp(IrpSp->FileObject->FileName.Buffer, L"\\downcall")) - IrpSp->FileObject->FsContext2 = COMM_DOWNCALL; - else if (!wcscmp(IrpSp->FileObject->FileName.Buffer, L"\\upcallhook")) - IrpSp->FileObject->FsContext2 = COMM_UPCALLHOOK; - } - if (!IrpSp->FileObject->FsContext2) - SYNC_FAIL2(STATUS_INVALID_DEVICE_REQUEST, 0); - - acc_token = SeQuerySubjectContextToken(&IrpSp->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext); - ASSERT(acc_token); - /* SeQueryAuthenticationIdToken */ - IrpSp->FileObject->FsContext = acc_token; - STATUS(STATUS_SUCCESS, FILE_OPENED); - break; - - case IRP_MJ_CLEANUP: - /* acc_token does not have to be released */ - case IRP_MJ_CLOSE: - STATUS(STATUS_SUCCESS, 0); - break; - - case IRP_MJ_WRITE: - /* we only process MDL writes */ - //_asm int 3; - if (!Irp->MdlAddress || - !(ptr = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority))) /* should be LowPagePriority */ - SYNC_FAIL(STATUS_INSUFFICIENT_RESOURCES); - - if (!IrpSp->FileObject->FsContext || - !IrpSp->FileObject->FsContext2) - SYNC_FAIL(STATUS_INVALID_HANDLE); - - if (IrpSp->FileObject->FsContext2 == COMM_UPCALLHOOK) - { - rpc_recv(ptr, IrpSp->Parameters.Write.Length); - STATUS(STATUS_SUCCESS, IrpSp->Parameters.Write.Length); - } - else - STATUS(STATUS_INVALID_DEVICE_REQUEST, 0); - break; - case IRP_MJ_READ: - if (!Irp->MdlAddress || !(ptr = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority))) // should be LowPagePriority - _asm int 3; - - if (IrpSp->FileObject->FsContext2 == COMM_UPCALLHOOK) - { - /*timeout.QuadPart = -10000000L;*/ - timeout.QuadPart = -100000000L; - KeWaitForSingleObject(&comExt->outEvent, Executive, KernelMode, FALSE, &timeout); - - if (!rpc_send(ptr, IrpSp->Parameters.Read.Length, &read)) - { - KeClearEvent(&comExt->outEvent); - KeWaitForSingleObject(&comExt->outEvent, Executive, KernelMode/*UserMode*/, FALSE, &timeout); - if (!rpc_send(ptr, IrpSp->Parameters.Read.Length, &read)) - { - KeClearEvent(&comExt->outEvent); - SYNC_FAIL(STATUS_UNSUCCESSFUL); - } - } - SYNC_FAIL2(STATUS_SUCCESS, read); - } - else - STATUS(STATUS_INVALID_DEVICE_REQUEST, 0); - break; - case IRP_MJ_DEVICE_CONTROL: - return AfsRdrDeviceControl(DeviceObject, Irp, IrpSp, NULL); - default: - STATUS(STATUS_INVALID_DEVICE_REQUEST, 0); - break; - } - -ret = Irp->IoStatus.Status; -COMPLETE; -return ret; + IO_STACK_LOCATION *IrpSp, *IrpSpClient; + NTSTATUS ret; + struct ComExtension *ext; + void *ptr, *ptr2; + rpc_t find, *find_ptr; + LARGE_INTEGER timeout; + struct afsFcb *fcb; + rpc_t *rpc, **rpcp; + ULONG len; + ULONG code, read; + PACCESS_TOKEN acc_token; + + ext = (struct ComExtension *)DeviceObject->DeviceExtension; + IrpSp = IoGetCurrentIrpStackLocation(Irp); + + switch (IrpSp->MajorFunction) + { + case IRP_MJ_CREATE: + IrpSp->FileObject->FsContext = 0; + IrpSp->FileObject->FsContext2 = 0; + if (IrpSp->FileObject->FileName.Length) + { + /* ioctls come from fs, vos, bos, etc. using a pre-existing interface */ + /* downcalls come from afsd, using a new interface */ + /* upcall hooks come from afsd */ + if (!wcscmp(IrpSp->FileObject->FileName.Buffer, L"\\ioctl")) + IrpSp->FileObject->FsContext2 = COMM_IOCTL; + else if (!wcscmp(IrpSp->FileObject->FileName.Buffer, L"\\downcall")) + IrpSp->FileObject->FsContext2 = COMM_DOWNCALL; + else if (!wcscmp(IrpSp->FileObject->FileName.Buffer, L"\\upcallhook")) + IrpSp->FileObject->FsContext2 = COMM_UPCALLHOOK; + } + if (!IrpSp->FileObject->FsContext2) + SYNC_FAIL2(STATUS_INVALID_DEVICE_REQUEST, 0); + + acc_token = SeQuerySubjectContextToken(&IrpSp->Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext); + ASSERT(acc_token); + /* SeQueryAuthenticationIdToken */ + IrpSp->FileObject->FsContext = acc_token; + STATUS(STATUS_SUCCESS, FILE_OPENED); + break; + + case IRP_MJ_CLEANUP: + /* acc_token does not have to be released */ + case IRP_MJ_CLOSE: + STATUS(STATUS_SUCCESS, 0); + break; + + case IRP_MJ_WRITE: + /* we only process MDL writes */ + //_asm int 3; + if (!Irp->MdlAddress || + !(ptr = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority))) /* should be LowPagePriority */ + SYNC_FAIL(STATUS_INSUFFICIENT_RESOURCES); + + if (!IrpSp->FileObject->FsContext || + !IrpSp->FileObject->FsContext2) + SYNC_FAIL(STATUS_INVALID_HANDLE); + + if (IrpSp->FileObject->FsContext2 == COMM_UPCALLHOOK) + { + rpc_recv(ptr, IrpSp->Parameters.Write.Length); + STATUS(STATUS_SUCCESS, IrpSp->Parameters.Write.Length); + } + else + STATUS(STATUS_INVALID_DEVICE_REQUEST, 0); + break; + case IRP_MJ_READ: + if (!Irp->MdlAddress || !(ptr = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority))) // should be LowPagePriority + _asm int 3; + + if (IrpSp->FileObject->FsContext2 == COMM_UPCALLHOOK) + { + /*timeout.QuadPart = -10000000L;*/ + timeout.QuadPart = -100000000L; + KeWaitForSingleObject(&comExt->outEvent, Executive, KernelMode, FALSE, &timeout); + + if (!rpc_send(ptr, IrpSp->Parameters.Read.Length, &read)) + { + KeClearEvent(&comExt->outEvent); + KeWaitForSingleObject(&comExt->outEvent, Executive, KernelMode/*UserMode*/, FALSE, &timeout); + if (!rpc_send(ptr, IrpSp->Parameters.Read.Length, &read)) + { + KeClearEvent(&comExt->outEvent); + SYNC_FAIL(STATUS_UNSUCCESSFUL); + } + } + SYNC_FAIL2(STATUS_SUCCESS, read); + } + else + STATUS(STATUS_INVALID_DEVICE_REQUEST, 0); + break; + case IRP_MJ_DEVICE_CONTROL: + return AfsRdrDeviceControl(DeviceObject, Irp, IrpSp, NULL); + default: + STATUS(STATUS_INVALID_DEVICE_REQUEST, 0); + break; + } + + ret = Irp->IoStatus.Status; + COMPLETE; + return ret; } // handles all irp's for primary (fs) device NTSTATUS Dispatch(DEVICE_OBJECT *DeviceObject, IRP *Irp) { -IO_STACK_LOCATION *IrpSp; -NTSTATUS ret; -afs_fcb_t *fcb; -afs_ccb_t *ccb; + IO_STACK_LOCATION *IrpSp; + NTSTATUS ret; + afs_fcb_t *fcb; + afs_ccb_t *ccb; -if (DeviceObject->DeviceType == FILE_DEVICE_DATALINK) + if (DeviceObject->DeviceType == FILE_DEVICE_DATALINK) return ComDispatch(DeviceObject, Irp); -IrpSp = IoGetCurrentIrpStackLocation(Irp); + IrpSp = IoGetCurrentIrpStackLocation(Irp); -rpt4(("irp", "%s min %d on %d (%ws) %x %x", IrpMjFuncDesc[IrpSp->MajorFunction], IrpSp->MinorFunction, 0/*ExtractFid(IrpSp->FileObject->FsContext)*/, IrpSp->FileObject->FileName.Buffer, IrpSp->Flags, IrpSp->Parameters.Create.Options)); + rpt4(("irp", "%s min %d on %d (%ws) %x %x", IrpMjFuncDesc[IrpSp->MajorFunction], IrpSp->MinorFunction, 0/*ExtractFid(IrpSp->FileObject->FsContext)*/, IrpSp->FileObject->FileName.Buffer, IrpSp->Flags, IrpSp->Parameters.Create.Options)); -fcb = IrpSp->FileObject->FsContext;//FindFcb(IrpSp->FileObject); -if (IrpSp->MajorFunction != IRP_MJ_CREATE) - ASSERT(fcb); + fcb = IrpSp->FileObject->FsContext;//FindFcb(IrpSp->FileObject); + if (IrpSp->MajorFunction != IRP_MJ_CREATE) + ASSERT(fcb); -if (IrpSp->FileObject && IrpSp->FileObject->FsContext2) - { + if (IrpSp->FileObject && IrpSp->FileObject->FsContext2) + { ccb = IrpSp->FileObject->FsContext2; rpc_set_context(ccb->token); - } - -switch (IrpSp->MajorFunction) - { - case IRP_MJ_CREATE: - ret = AfsRdrCreate(DeviceObject, Irp, IrpSp, NULL); break; - case IRP_MJ_DIRECTORY_CONTROL: - ret = AfsRdrDirCtrl(DeviceObject, Irp, IrpSp, fcb); break; - case IRP_MJ_READ: - ret = AfsRdrRead(DeviceObject, Irp, IrpSp, fcb); break; - case IRP_MJ_WRITE: - ret = AfsRdrWrite(DeviceObject, Irp, IrpSp, fcb); break; - case IRP_MJ_CLOSE: - ret = AfsRdrClose(DeviceObject, Irp, IrpSp, fcb); break; - case IRP_MJ_QUERY_INFORMATION: - ret = AfsRdrQueryInfo(DeviceObject, Irp, IrpSp, fcb); break; - case IRP_MJ_DEVICE_CONTROL: - ret = AfsRdrDeviceControl(DeviceObject, Irp, IrpSp, fcb); break; - case IRP_MJ_CLEANUP: - ret = AfsRdrCleanup(DeviceObject, Irp, IrpSp, fcb); break; - case IRP_MJ_LOCK_CONTROL: - ret = AfsRdrLockCtrl(DeviceObject, Irp, IrpSp, fcb); break; - case IRP_MJ_QUERY_VOLUME_INFORMATION: - ret = AfsRdrQueryVol(DeviceObject, Irp, IrpSp); break; - case IRP_MJ_SHUTDOWN: - ret = AfsRdrShutdown(DeviceObject, Irp, IrpSp); break; - case IRP_MJ_FILE_SYSTEM_CONTROL: - if (IrpSp->MinorFunction == IRP_MN_USER_FS_REQUEST && - (IrpSp->Parameters.FileSystemControl.FsControlCode == FSCTL_REQUEST_OPLOCK_LEVEL_1 || - IrpSp->Parameters.FileSystemControl.FsControlCode == FSCTL_REQUEST_OPLOCK_LEVEL_2 || - IrpSp->Parameters.FileSystemControl.FsControlCode == FSCTL_REQUEST_BATCH_OPLOCK || - IrpSp->Parameters.FileSystemControl.FsControlCode == FSCTL_REQUEST_FILTER_OPLOCK)) - STATUS(STATUS_OPLOCK_NOT_GRANTED, 0); - else - STATUS(STATUS_INVALID_DEVICE_REQUEST/*STATUS_NOT_IMPLEMENTED*//*STATUS_INVALID_PARAMETER*/, 0); + } + + switch (IrpSp->MajorFunction) + { + case IRP_MJ_CREATE: + ret = AfsRdrCreate(DeviceObject, Irp, IrpSp, NULL); + break; + case IRP_MJ_DIRECTORY_CONTROL: + ret = AfsRdrDirCtrl(DeviceObject, Irp, IrpSp, fcb); + break; + case IRP_MJ_READ: + ret = AfsRdrRead(DeviceObject, Irp, IrpSp, fcb); + break; + case IRP_MJ_WRITE: + ret = AfsRdrWrite(DeviceObject, Irp, IrpSp, fcb); + break; + case IRP_MJ_CLOSE: + ret = AfsRdrClose(DeviceObject, Irp, IrpSp, fcb); + break; + case IRP_MJ_QUERY_INFORMATION: + ret = AfsRdrQueryInfo(DeviceObject, Irp, IrpSp, fcb); + break; + case IRP_MJ_DEVICE_CONTROL: + ret = AfsRdrDeviceControl(DeviceObject, Irp, IrpSp, fcb); + break; + case IRP_MJ_CLEANUP: + ret = AfsRdrCleanup(DeviceObject, Irp, IrpSp, fcb); + break; + case IRP_MJ_LOCK_CONTROL: + ret = AfsRdrLockCtrl(DeviceObject, Irp, IrpSp, fcb); + break; + case IRP_MJ_QUERY_VOLUME_INFORMATION: + ret = AfsRdrQueryVol(DeviceObject, Irp, IrpSp); + break; + case IRP_MJ_SHUTDOWN: + ret = AfsRdrShutdown(DeviceObject, Irp, IrpSp); + break; + case IRP_MJ_FILE_SYSTEM_CONTROL: + if (IrpSp->MinorFunction == IRP_MN_USER_FS_REQUEST && + (IrpSp->Parameters.FileSystemControl.FsControlCode == FSCTL_REQUEST_OPLOCK_LEVEL_1 || + IrpSp->Parameters.FileSystemControl.FsControlCode == FSCTL_REQUEST_OPLOCK_LEVEL_2 || + IrpSp->Parameters.FileSystemControl.FsControlCode == FSCTL_REQUEST_BATCH_OPLOCK || + IrpSp->Parameters.FileSystemControl.FsControlCode == FSCTL_REQUEST_FILTER_OPLOCK)) + STATUS(STATUS_OPLOCK_NOT_GRANTED, 0); + else + STATUS(STATUS_INVALID_DEVICE_REQUEST/*STATUS_NOT_IMPLEMENTED*//*STATUS_INVALID_PARAMETER*/, 0); ret = Irp->IoStatus.Status; - goto complete; - case IRP_MJ_SET_INFORMATION: - ret = AfsRdrSetInfo(DeviceObject, Irp, IrpSp, fcb); break; - case IRP_MJ_FLUSH_BUFFERS: - ret = AfsRdrFlushFile(DeviceObject, Irp, IrpSp, fcb); break; - default: - ret = AfsRdrNull(DeviceObject, Irp, IrpSp); break; - } -rpc_remove_context(); -return ret; - -complete: -rpc_remove_context(); -COMPLETE; -return ret; + goto complete; + case IRP_MJ_SET_INFORMATION: + ret = AfsRdrSetInfo(DeviceObject, Irp, IrpSp, fcb); + break; + case IRP_MJ_FLUSH_BUFFERS: + ret = AfsRdrFlushFile(DeviceObject, Irp, IrpSp, fcb); + break; + default: + ret = AfsRdrNull(DeviceObject, Irp, IrpSp); + break; + } + rpc_remove_context(); + return ret; + + complete: + rpc_remove_context(); + COMPLETE; + return ret; } BOOLEAN @@ -2246,45 +2281,45 @@ fastIoRead ( IN struct _DEVICE_OBJECT *DeviceObject ) { -BOOLEAN ret; -ULONG adj_len; -afs_fcb_t *fcb; - -fcb = FileObject->FsContext; -ASSERT(fcb); - -FsRtlEnterFileSystem(); -LOCK_PAGING_FCB; -adj_len = Length; -if (FileOffset->QuadPart > fcb->FileSize.QuadPart) - { + BOOLEAN ret; + ULONG adj_len; + afs_fcb_t *fcb; + + fcb = FileObject->FsContext; + ASSERT(fcb); + + FsRtlEnterFileSystem(); + LOCK_PAGING_FCB; + adj_len = Length; + if (FileOffset->QuadPart > fcb->FileSize.QuadPart) + { UNLOCK_PAGING_FCB; FsRtlExitFileSystem(); IoStatus->Status = STATUS_END_OF_FILE; IoStatus->Information = 0; return TRUE; - } -if (FileOffset->QuadPart + Length > fcb->FileSize.QuadPart) + } + if (FileOffset->QuadPart + Length > fcb->FileSize.QuadPart) adj_len = (ULONG)(fcb->FileSize.QuadPart - FileOffset->QuadPart); -try - { + try + { ret = CcCopyRead(FileObject, FileOffset, adj_len, Wait, Buffer, IoStatus); /*if (IoStatus->Status == STATUS_SUCCESS && - (adj_len < Length)) - IoStatus->Status = STATUS_END_OF_FILE;*/ -// KdPrint(("read %x at %x fast done %x\n", Length, (ULONG)FileOffset->QuadPart, IoStatus->Information)); + (adj_len < Length)) + IoStatus->Status = STATUS_END_OF_FILE;*/ + // KdPrint(("read %x at %x fast done %x\n", Length, (ULONG)FileOffset->QuadPart, IoStatus->Information)); FileObject->CurrentByteOffset.QuadPart += IoStatus->Information; UNLOCK_PAGING_FCB; FsRtlExitFileSystem(); - } -except (EXCEPTION_EXECUTE_HANDLER) - { + } + except (EXCEPTION_EXECUTE_HANDLER) + { UNLOCK_PAGING_FCB; FsRtlExitFileSystem(); return FALSE; - } -return ret; + } + return ret; } BOOLEAN @@ -2299,91 +2334,91 @@ fastIoWrite ( IN struct _DEVICE_OBJECT *DeviceObject ) { -BOOLEAN ret; -LARGE_INTEGER adj_end; -afs_fcb_t *fcb; + BOOLEAN ret; + LARGE_INTEGER adj_end; + afs_fcb_t *fcb; -fcb = FileObject->FsContext; -ASSERT(fcb); + fcb = FileObject->FsContext; + ASSERT(fcb); -FsRtlEnterFileSystem(); -LOCK_PAGING_FCB; + FsRtlEnterFileSystem(); + LOCK_PAGING_FCB; -if (FileOffset->QuadPart + Length > fcb->FileSize.QuadPart) - { + if (FileOffset->QuadPart + Length > fcb->FileSize.QuadPart) + { adj_end.QuadPart = fcb->FileSize.QuadPart + Length; fcb->AllocationSize = fcb->FileSize = fcb->ValidDataLength = adj_end; LOCK_FCB; try - { - CcSetFileSizes(FileObject, (CC_FILE_SIZES*)&fcb->AllocationSize); - } + { + CcSetFileSizes(FileObject, (CC_FILE_SIZES*)&fcb->AllocationSize); + } except (EXCEPTION_EXECUTE_HANDLER) - { - UNLOCK_FCB; - UNLOCK_PAGING_FCB; - FsRtlExitFileSystem(); - return FALSE; - } + { + UNLOCK_FCB; + UNLOCK_PAGING_FCB; + FsRtlExitFileSystem(); + return FALSE; + } UNLOCK_FCB; - } + } -try - { + try + { ret = CcCopyWrite(FileObject, FileOffset, Length, Wait, Buffer); IoStatus->Status = ret?STATUS_SUCCESS:STATUS_UNSUCCESSFUL; IoStatus->Information = ret?Length:0; -// KdPrint(("write %x at %x fast done\n", Length, (ULONG)FileOffset->QuadPart)); + // KdPrint(("write %x at %x fast done\n", Length, (ULONG)FileOffset->QuadPart)); FileObject->CurrentByteOffset.QuadPart += IoStatus->Information; UNLOCK_PAGING_FCB; FsRtlExitFileSystem(); - } -except (EXCEPTION_EXECUTE_HANDLER) - { + } + except (EXCEPTION_EXECUTE_HANDLER) + { UNLOCK_PAGING_FCB; FsRtlExitFileSystem(); return FALSE; - } -return ret; + } + return ret; } RTL_GENERIC_COMPARE_RESULTS FcbCompareRoutine(struct _RTL_GENERIC_TABLE *Table, PVOID FirstStruct, PVOID SecondStruct) - { - afs_fcb_t *p1, *p2; - - p1 = (void*)*(afs_fcb_t**)FirstStruct; p2 = (void*)*(afs_fcb_t**)SecondStruct; - if (p1->fid < p2->fid) - return GenericLessThan; - if (p1->fid > p2->fid) - return GenericGreaterThan; - return GenericEqual; - } +{ + afs_fcb_t *p1, *p2; + + p1 = (void*)*(afs_fcb_t**)FirstStruct; p2 = (void*)*(afs_fcb_t**)SecondStruct; + if (p1->fid < p2->fid) + return GenericLessThan; + if (p1->fid > p2->fid) + return GenericGreaterThan; + return GenericEqual; +} RTL_GENERIC_COMPARE_RESULTS ReqCompareRoutine(struct _RTL_GENERIC_TABLE *Table, PVOID FirstStruct, PVOID SecondStruct) - { - rpc_t *p1, *p2; - - p1 = *(rpc_t**)FirstStruct; p2 = *(rpc_t**)SecondStruct; - if (p1->key < p2->key) - return GenericLessThan; - if (p1->key > p2->key) - return GenericGreaterThan; - return GenericEqual; - } +{ + rpc_t *p1, *p2; + + p1 = *(rpc_t**)FirstStruct; p2 = *(rpc_t**)SecondStruct; + if (p1->key < p2->key) + return GenericLessThan; + if (p1->key > p2->key) + return GenericGreaterThan; + return GenericEqual; +} PVOID AllocateRoutine(struct _RTL_GENERIC_TABLE *Table, CLONG ByteSize) - { - PVOID ret; - ret = ExAllocatePoolWithTag(NonPagedPool, ByteSize, AFS_RDR_TAG); - ASSERT(ret); - RtlZeroMemory(ret, ByteSize); - return ret; - } +{ + PVOID ret; + ret = ExAllocatePoolWithTag(NonPagedPool, ByteSize, AFS_RDR_TAG); + ASSERT(ret); + RtlZeroMemory(ret, ByteSize); + return ret; +} VOID FreeRoutine(struct _RTL_GENERIC_TABLE *Table, PVOID Buffer) - { - ExFreePoolWithTag(Buffer, AFS_RDR_TAG); - } +{ + ExFreePoolWithTag(Buffer, AFS_RDR_TAG); +} //KSPIN_LOCK rpc_lock; //KIRQL irql; @@ -2391,106 +2426,106 @@ FAST_MUTEX rpc_lock; void ifs_lock_rpcs() { -ExAcquireFastMutex(&rpc_lock); -//KeAcquireSpinLock(&rpc_lock, &irql); + ExAcquireFastMutex(&rpc_lock); + //KeAcquireSpinLock(&rpc_lock, &irql); } void ifs_unlock_rpcs() { -ExReleaseFastMutex(&rpc_lock); -//KeReleaseSpinLock(&rpc_lock, irql); + ExReleaseFastMutex(&rpc_lock); + //KeReleaseSpinLock(&rpc_lock, irql); } NTSTATUS DriverEntry(DRIVER_OBJECT *DriverObject, UNICODE_STRING *RegistryPath) { -NTSTATUS err; -UNICODE_STRING rdrName, comName, userModeName, userModeCom; -int x; -IO_STATUS_BLOCK status; -FAST_IO_DISPATCH *fastIoDispatch; + NTSTATUS err; + UNICODE_STRING rdrName, comName, userModeName, userModeCom; + int x; + IO_STATUS_BLOCK status; + FAST_IO_DISPATCH *fastIoDispatch; -//_asm int 3; + //_asm int 3; -//try { + //try { #ifdef RPT_ENA -REPORT = rptOpen(NULL, "afskern"); + REPORT = rptOpen(NULL, "afskern"); #endif -rpt0(("init", "rpt initialized at %x", REPORT)); + rpt0(("init", "rpt initialized at %x", REPORT)); -RtlInitUnicodeString(&rdrName, L"\\Device\\afsrdr"); -RtlInitUnicodeString(&comName, L"\\Device\\afscom"); + RtlInitUnicodeString(&rdrName, L"\\Device\\afsrdr"); + RtlInitUnicodeString(&comName, L"\\Device\\afscom"); -rpt0(("init", "kern initializing")); -//KeInitializeSpinLock(&rpc_lock); -ExInitializeFastMutex(&rpc_lock); + rpt0(("init", "kern initializing")); + //KeInitializeSpinLock(&rpc_lock); + ExInitializeFastMutex(&rpc_lock); -IoAllocateDriverObjectExtension(DriverObject, (void *)0x394389f7, sizeof(FAST_IO_DISPATCH), &fastIoDispatch); -RtlZeroMemory(fastIoDispatch, sizeof(FAST_IO_DISPATCH)); -fastIoDispatch->SizeOfFastIoDispatch = sizeof(FAST_IO_DISPATCH); -fastIoDispatch->FastIoRead = fastIoRead; -fastIoDispatch->FastIoWrite = fastIoWrite; -DriverObject->FastIoDispatch = fastIoDispatch; + IoAllocateDriverObjectExtension(DriverObject, (void *)0x394389f7, sizeof(FAST_IO_DISPATCH), &fastIoDispatch); + RtlZeroMemory(fastIoDispatch, sizeof(FAST_IO_DISPATCH)); + fastIoDispatch->SizeOfFastIoDispatch = sizeof(FAST_IO_DISPATCH); + fastIoDispatch->FastIoRead = fastIoRead; + fastIoDispatch->FastIoWrite = fastIoWrite; + DriverObject->FastIoDispatch = fastIoDispatch; -for (x = 0; x < IRP_MJ_MAXIMUM_FUNCTION; x++) + for (x = 0; x < IRP_MJ_MAXIMUM_FUNCTION; x++) DriverObject->MajorFunction[x] = Dispatch; -DriverObject->DriverUnload = AfsRdrUnload; + DriverObject->DriverUnload = AfsRdrUnload; -err = IoCreateDevice(DriverObject, sizeof(struct AfsRdrExtension)*2, &rdrName, FILE_DEVICE_NETWORK_FILE_SYSTEM, /*FILE_REMOTE_DEVICE*/0, FALSE, &RdrDevice); -if (!NT_SUCCESS(STATUS_SUCCESS)) + err = IoCreateDevice(DriverObject, sizeof(struct AfsRdrExtension)*2, &rdrName, FILE_DEVICE_NETWORK_FILE_SYSTEM, /*FILE_REMOTE_DEVICE*/0, FALSE, &RdrDevice); + if (!NT_SUCCESS(STATUS_SUCCESS)) return STATUS_UNSUCCESSFUL; -err = IoCreateDevice(DriverObject, sizeof(struct ComExtension)*2, &comName, FILE_DEVICE_DATALINK, 0, FALSE, &ComDevice); -if (!NT_SUCCESS(STATUS_SUCCESS)) + err = IoCreateDevice(DriverObject, sizeof(struct ComExtension)*2, &comName, FILE_DEVICE_DATALINK, 0, FALSE, &ComDevice); + if (!NT_SUCCESS(STATUS_SUCCESS)) return STATUS_UNSUCCESSFUL; -RdrDevice->Flags |= DO_DIRECT_IO; -RdrDevice->StackSize = 5; /* could this be zero? */ -rdrExt = ((struct AfsRdrExtension*)RdrDevice->DeviceExtension); -RtlZeroMemory(rdrExt, sizeof(struct AfsRdrExtension)); - -/* could raise exception */ -FsRtlNotifyInitializeSync(&rdrExt->notifyList); -InitializeListHead(&rdrExt->listHead); - -rdrExt->callbacks.AcquireForLazyWrite = lazyWriteLock; -rdrExt->callbacks.ReleaseFromLazyWrite = lazyWriteUnlock; -rdrExt->callbacks.AcquireForReadAhead = readAheadLock; -rdrExt->callbacks.ReleaseFromReadAhead = readAheadUnlock; -ExInitializeNPagedLookasideList(&rdrExt->fcbMemList, NULL, NULL, 0, sizeof(afs_fcb_t), AFS_RDR_TAG, 0); -ExInitializeNPagedLookasideList(&rdrExt->ccbMemList, NULL, NULL, 0, sizeof(afs_ccb_t), AFS_RDR_TAG, 0); -ExInitializeFastMutex(&rdrExt->fcbLock); -RtlInitializeGenericTable(&rdrExt->fcbTable, FcbCompareRoutine, AllocateRoutine, FreeRoutine, NULL); - - -ComDevice->Flags |= DO_DIRECT_IO; -ComDevice->StackSize = 5; // ?? -comExt = ((struct ComExtension*)ComDevice->DeviceExtension); -RtlZeroMemory(comExt, sizeof(struct ComExtension)); - -//ExInitializeNPagedLookasideList(&comExt->outMemList, NULL, NULL, 0, sizeof(struct KOutEntry)+100, AFS_RDR_TAG, 0); -InitializeListHead(&comExt->outReqList); -KeInitializeSpinLock(&comExt->outLock); -ExInitializeFastMutex(&comExt->inLock); -RtlInitializeGenericTable(&comExt->inTable, ReqCompareRoutine, AllocateRoutine, FreeRoutine, NULL); -KeInitializeEvent(&comExt->outEvent, NotificationEvent, TRUE); -KeInitializeEvent(&comExt->cancelEvent, NotificationEvent, TRUE); - -comExt->rdr = rdrExt; -rdrExt->com = comExt; - -RtlInitUnicodeString(&userModeCom, L"\\DosDevices\\afscom"); -err = IoCreateSymbolicLink(&userModeCom, &comName); - -/*RtlInitUnicodeString(&rdrName, L"\\Device\\afsrdr\\1\\CITI.UMICH.EDU"); -RtlInitUnicodeString(&userModeName, L"\\DosDevices\\W:"); -err = IoCreateSymbolicLink(&userModeName, &rdrName);*/ - -/*} except(EXCEPTION_EXECUTE_HANDLER) - { - _asm int 3; - //logerror(); - return -1; - }*/ - -KdPrint(("DriverEntry exiting.\n")); -return STATUS_SUCCESS; + RdrDevice->Flags |= DO_DIRECT_IO; + RdrDevice->StackSize = 5; /* could this be zero? */ + rdrExt = ((struct AfsRdrExtension*)RdrDevice->DeviceExtension); + RtlZeroMemory(rdrExt, sizeof(struct AfsRdrExtension)); + + /* could raise exception */ + FsRtlNotifyInitializeSync(&rdrExt->notifyList); + InitializeListHead(&rdrExt->listHead); + + rdrExt->callbacks.AcquireForLazyWrite = lazyWriteLock; + rdrExt->callbacks.ReleaseFromLazyWrite = lazyWriteUnlock; + rdrExt->callbacks.AcquireForReadAhead = readAheadLock; + rdrExt->callbacks.ReleaseFromReadAhead = readAheadUnlock; + ExInitializeNPagedLookasideList(&rdrExt->fcbMemList, NULL, NULL, 0, sizeof(afs_fcb_t), AFS_RDR_TAG, 0); + ExInitializeNPagedLookasideList(&rdrExt->ccbMemList, NULL, NULL, 0, sizeof(afs_ccb_t), AFS_RDR_TAG, 0); + ExInitializeFastMutex(&rdrExt->fcbLock); + RtlInitializeGenericTable(&rdrExt->fcbTable, FcbCompareRoutine, AllocateRoutine, FreeRoutine, NULL); + + + ComDevice->Flags |= DO_DIRECT_IO; + ComDevice->StackSize = 5; // ?? + comExt = ((struct ComExtension*)ComDevice->DeviceExtension); + RtlZeroMemory(comExt, sizeof(struct ComExtension)); + + //ExInitializeNPagedLookasideList(&comExt->outMemList, NULL, NULL, 0, sizeof(struct KOutEntry)+100, AFS_RDR_TAG, 0); + InitializeListHead(&comExt->outReqList); + KeInitializeSpinLock(&comExt->outLock); + ExInitializeFastMutex(&comExt->inLock); + RtlInitializeGenericTable(&comExt->inTable, ReqCompareRoutine, AllocateRoutine, FreeRoutine, NULL); + KeInitializeEvent(&comExt->outEvent, NotificationEvent, TRUE); + KeInitializeEvent(&comExt->cancelEvent, NotificationEvent, TRUE); + + comExt->rdr = rdrExt; + rdrExt->com = comExt; + + RtlInitUnicodeString(&userModeCom, L"\\DosDevices\\afscom"); + err = IoCreateSymbolicLink(&userModeCom, &comName); + + /*RtlInitUnicodeString(&rdrName, L"\\Device\\afsrdr\\1\\CITI.UMICH.EDU"); + RtlInitUnicodeString(&userModeName, L"\\DosDevices\\W:"); + err = IoCreateSymbolicLink(&userModeName, &rdrName);*/ + + /*} except(EXCEPTION_EXECUTE_HANDLER) + { + _asm int 3; + //logerror(); + return -1; + }*/ + + KdPrint(("DriverEntry exiting.\n")); + return STATUS_SUCCESS; } diff --git a/src/WINNT/afsrdr/ifs_rpc.c b/src/WINNT/afsrdr/ifs_rpc.c index b7d924bf4..07139f6e3 100644 --- a/src/WINNT/afsrdr/ifs_rpc.c +++ b/src/WINNT/afsrdr/ifs_rpc.c @@ -63,1017 +63,1017 @@ rpc_send_mdl(rpc_t *rpc, char *out_buf); /* internal timing functions (not used) */ #ifdef RPC_KERN #define TIMING_START() LARGE_INTEGER start, stop; \ - start.QuadPart = KeQueryInterruptTime(); + start.QuadPart = KeQueryInterruptTime(); #define TIMING_END(name) stop.QuadPart = KeQueryInterruptTime(); \ - rpt5((name, "%s %d", name, (ULONG)(stop.QuadPart - start.QuadPart))); + rpt5((name, "%s %d", name, (ULONG)(stop.QuadPart - start.QuadPart))); #endif /* rpc security kernel functions */ #ifdef RPC_KERN struct rpc_cred_map_entry - { - void *token; - PETHREAD thread; - }; +{ + void *token; + PETHREAD thread; +}; struct rpc_cred_map_entry cred_map[20]; rpc_t *rpc_list_head = NULL; rpc_set_context(void *context) - { - int x, empty, ret; - PETHREAD thd; - - thd = PsGetCurrentThread(); - empty = -1; - ret = 0; - - // LOCKLOCK - for (x = 0; x < 20; x++) - { - if (cred_map[x].thread == NULL) - empty = x; - if (cred_map[x].thread == thd) - { - cred_map[x].token = context; - goto done; - } - } - if (empty != -1) - { - cred_map[empty].thread = thd; - cred_map[empty].token = context; - } - else - ret = -1; - - done: - // UNLOCKUNLOCK - return ret; - } +{ + int x, empty, ret; + PETHREAD thd; + + thd = PsGetCurrentThread(); + empty = -1; + ret = 0; + + // LOCKLOCK + for (x = 0; x < 20; x++) + { + if (cred_map[x].thread == NULL) + empty = x; + if (cred_map[x].thread == thd) + { + cred_map[x].token = context; + goto done; + } + } + if (empty != -1) + { + cred_map[empty].thread = thd; + cred_map[empty].token = context; + } + else + ret = -1; + + done: + // UNLOCKUNLOCK + return ret; +} void *rpc_get_context() - { - int x; - PETHREAD thd; +{ + int x; + PETHREAD thd; - thd = PsGetCurrentThread(); + thd = PsGetCurrentThread(); - // no lock - for (x = 0; x < 20; x++) - if (cred_map[x].thread == thd) - return cred_map[x].token; - // no unlock - return NULL; - } + // no lock + for (x = 0; x < 20; x++) + if (cred_map[x].thread == thd) + return cred_map[x].token; + // no unlock + return NULL; +} rpc_remove_context() - { - int x; - PETHREAD thd; - - thd = PsGetCurrentThread(); - // no lock - for (x = 0; x < 20; x++) - if (cred_map[x].thread == thd) - { - cred_map[x].token = NULL; - cred_map[x].thread = NULL; - return 0; - } - - // no unlock - return -1; - } +{ + int x; + PETHREAD thd; + + thd = PsGetCurrentThread(); + // no lock + for (x = 0; x < 20; x++) + if (cred_map[x].thread == thd) + { + cred_map[x].token = NULL; + cred_map[x].thread = NULL; + return 0; + } + + // no unlock + return -1; +} #endif /* rpc internal functions for kernel */ #ifdef RPC_KERN rpc_t *rpc_create(int size_hint) - { - ULONG size; - rpc_t *rpc; - SECURITY_SUBJECT_CONTEXT subj_context; - PACCESS_TOKEN acc_token; - LUID auth_id; - LARGE_INTEGER user_id; - NTSTATUS status; - HANDLE token; - - token = rpc_get_context(); - ASSERT(token); - status = SeQueryAuthenticationIdToken(token, &auth_id); - - user_id.LowPart = auth_id.LowPart; - user_id.HighPart = auth_id.HighPart; - - ifs_lock_rpcs(); - - if (!(rpc = rpc_upgrade(NULL, 0, 1))) - { - size = sizeof(rpc_t) + 4096*10; - rpc = ExAllocatePoolWithTag(NonPagedPool, size, 0x1234); - if (!rpc) - _asm int 3; - memset(rpc, 0, size); - rpc->next = rpc_list_head; - rpc_list_head = rpc; - rpc_upgrade(rpc, 0, 1); - } - - rpc->out_buf = rpc->out_pos = (char*)(rpc+1); - rpc->in_buf = rpc->in_pos = ((char*)(rpc+1))+2048*10; - - rpc->key = rand() + 10; - rpc_marshal_long(rpc, rpc->key); - rpc->bulk_out_len = (ULONG*)rpc->out_pos; - rpc_marshal_long(rpc, 0); - - /*SeCaptureSubjectContext(&subj_context); - acc_token = SeQuerySubjectContextToken(&subj_context); - status = SeQueryAuthenticationIdToken(acc_token, &auth_id);*/ - /**token = rpc_get_context(); - ASSERT(token); - status = SeQueryAuthenticationIdToken(token, &auth_id); - - user_id.LowPart = auth_id.LowPart; - user_id.HighPart = auth_id.HighPart; - SeReleaseSubjectContext(&subj_context);*/ - - rpc_marshal_longlong(rpc, user_id); - - ifs_unlock_rpcs(); - - return rpc; - } +{ + ULONG size; + rpc_t *rpc; + SECURITY_SUBJECT_CONTEXT subj_context; + PACCESS_TOKEN acc_token; + LUID auth_id; + LARGE_INTEGER user_id; + NTSTATUS status; + HANDLE token; + + token = rpc_get_context(); + ASSERT(token); + status = SeQueryAuthenticationIdToken(token, &auth_id); + + user_id.LowPart = auth_id.LowPart; + user_id.HighPart = auth_id.HighPart; + + ifs_lock_rpcs(); + + if (!(rpc = rpc_upgrade(NULL, 0, 1))) + { + size = sizeof(rpc_t) + 4096*10; + rpc = ExAllocatePoolWithTag(NonPagedPool, size, 0x1234); + if (!rpc) + _asm int 3; + memset(rpc, 0, size); + rpc->next = rpc_list_head; + rpc_list_head = rpc; + rpc_upgrade(rpc, 0, 1); + } + + rpc->out_buf = rpc->out_pos = (char*)(rpc+1); + rpc->in_buf = rpc->in_pos = ((char*)(rpc+1))+2048*10; + + rpc->key = rand() + 10; + rpc_marshal_long(rpc, rpc->key); + rpc->bulk_out_len = (ULONG*)rpc->out_pos; + rpc_marshal_long(rpc, 0); + + /*SeCaptureSubjectContext(&subj_context); + acc_token = SeQuerySubjectContextToken(&subj_context); + status = SeQueryAuthenticationIdToken(acc_token, &auth_id);*/ + /**token = rpc_get_context(); + ASSERT(token); + status = SeQueryAuthenticationIdToken(token, &auth_id); + + user_id.LowPart = auth_id.LowPart; + user_id.HighPart = auth_id.HighPart; + SeReleaseSubjectContext(&subj_context);*/ + + rpc_marshal_longlong(rpc, user_id); + + ifs_unlock_rpcs(); + + return rpc; +} void rpc_destroy(rpc_t *rpc) - { - rpc_t *curr; - int count; +{ + rpc_t *curr; + int count; - /*ExFreePoolWithTag(rpc, 0x1234);*/ - ifs_lock_rpcs(); + /*ExFreePoolWithTag(rpc, 0x1234);*/ + ifs_lock_rpcs(); - if (rpc_upgrade(rpc, -1, 0)) - ; + if (rpc_upgrade(rpc, -1, 0)) + ; - ifs_unlock_rpcs(); - } + ifs_unlock_rpcs(); +} #endif /* rpc internal functions for usermode */ #ifndef RPC_KERN rpc_t *rpc_create(int size_hint) - { - ULONG size; - rpc_t *rpc; - ULONG status; +{ + ULONG size; + rpc_t *rpc; + ULONG status; - size = sizeof(rpc_t) + 4096; - rpc = malloc(size); - if (!rpc) - _asm int 3; - memset(rpc, 0, size); + size = sizeof(rpc_t) + 4096; + rpc = malloc(size); + if (!rpc) + _asm int 3; + memset(rpc, 0, size); - rpc->out_buf = rpc->out_pos = (char*)(rpc+1); - rpc->in_buf = rpc->in_pos = ((char*)(rpc+1))+2048; + rpc->out_buf = rpc->out_pos = (char*)(rpc+1); + rpc->in_buf = rpc->in_pos = ((char*)(rpc+1))+2048; - rpc->key = rand() + 10; - rpc_marshal_long(rpc, rpc->key); + rpc->key = rand() + 10; + rpc_marshal_long(rpc, rpc->key); - return rpc; - } + return rpc; +} void rpc_destroy(rpc_t *rpc) - { - if (!rpc) - return; - //_asm int 3; +{ + if (!rpc) + return; + //_asm int 3; - free(rpc); - } + free(rpc); +} rpc_transact(rpc_t *rpc) - { - HANDLE hf; - int ret; - ULONG header_len; - DWORD err, read = 0; +{ + HANDLE hf; + int ret; + ULONG header_len; + DWORD err, read = 0; - if (!rpc) - return IFSL_GENERIC_FAILURE; + if (!rpc) + return IFSL_GENERIC_FAILURE; - header_len = rpc->out_pos - rpc->out_buf; + header_len = rpc->out_pos - rpc->out_buf; - read = 2048; - return ifs_TransactRpc(rpc->out_buf, header_len, rpc->in_buf, &read); - } + read = 2048; + return ifs_TransactRpc(rpc->out_buf, header_len, rpc->in_buf, &read); +} #endif /* upcall stubs */ #ifdef RPC_KERN uc_namei(WCHAR *name, ULONG *fid) - { - rpc_t *rpc; - ULONG status; - MDL *mdl; - TIMING_START(); - /* put namei cache here */ +{ + rpc_t *rpc; + ULONG status; + MDL *mdl; + TIMING_START(); + /* put namei cache here */ - rpc = rpc_create(0); + rpc = rpc_create(0); - rpc_marshal_long(rpc, RPC_NAMEI); - rpc_marshal_long(rpc, wcslen(name)); + rpc_marshal_long(rpc, RPC_NAMEI); + rpc_marshal_long(rpc, wcslen(name)); - rpc_queue_bulk(rpc, (void*)name, (wcslen(name)+1)*sizeof(wchar_t), NULL, 0); + rpc_queue_bulk(rpc, (void*)name, (wcslen(name)+1)*sizeof(wchar_t), NULL, 0); - if (!rpc_wait(rpc, RPC_TIMEOUT_SHORT)) - { - rpc_cancel(rpc); - rpt0(("cancel", "cancel namei")); - return IFSL_RPC_TIMEOUT; - } + if (!rpc_wait(rpc, RPC_TIMEOUT_SHORT)) + { + rpc_cancel(rpc); + rpt0(("cancel", "cancel namei")); + return IFSL_RPC_TIMEOUT; + } - rpc_unmarshal_long(rpc, &status); - rpc_unmarshal_long(rpc, fid); + rpc_unmarshal_long(rpc, &status); + rpc_unmarshal_long(rpc, fid); - rpc_destroy(rpc); - TIMING_END("namei"); - return status; - } + rpc_destroy(rpc); + TIMING_END("namei"); + return status; +} uc_check_access(ULONG fid, ULONG access, ULONG *granted) - { - rpc_t *rpc; - ULONG status; - TIMING_START(); +{ + rpc_t *rpc; + ULONG status; + TIMING_START(); - rpc = rpc_create(0); + rpc = rpc_create(0); - rpc_marshal_long(rpc, RPC_CHECK_ACCESS); - rpc_marshal_long(rpc, fid); - rpc_marshal_long(rpc, access); + rpc_marshal_long(rpc, RPC_CHECK_ACCESS); + rpc_marshal_long(rpc, fid); + rpc_marshal_long(rpc, access); - rpc_queue(rpc); - if (!rpc_wait(rpc, RPC_TIMEOUT_SHORT)) - { - rpc_cancel(rpc); - rpt0(("cancel", "cancel access")); - return IFSL_RPC_TIMEOUT; - } + rpc_queue(rpc); + if (!rpc_wait(rpc, RPC_TIMEOUT_SHORT)) + { + rpc_cancel(rpc); + rpt0(("cancel", "cancel access")); + return IFSL_RPC_TIMEOUT; + } - rpc_unmarshal_long(rpc, &status); - rpc_unmarshal_long(rpc, granted); + rpc_unmarshal_long(rpc, &status); + rpc_unmarshal_long(rpc, granted); - rpc_destroy(rpc); - TIMING_END("access"); - return status; - } + rpc_destroy(rpc); + TIMING_END("access"); + return status; +} uc_create(WCHAR *name, ULONG attribs, LARGE_INTEGER alloc, ULONG access, ULONG *granted, ULONG *fid) - { - rpc_t *rpc; - ULONG status; - TIMING_START(); - - rpc = rpc_create(0); - - rpc_marshal_long(rpc, RPC_CREATE); - rpc_marshal_long(rpc, attribs); - rpc_marshal_longlong(rpc, alloc); - rpc_marshal_long(rpc, access); - - rpc_queue_bulk(rpc, (void*)name, (wcslen(name)+1)*sizeof(wchar_t), NULL, 0); - if (!rpc_wait(rpc, RPC_TIMEOUT_SHORT)) - { - rpc_cancel(rpc); - rpt0(("cancel", "cancel create")); - return IFSL_RPC_TIMEOUT; - } - - rpc_unmarshal_long(rpc, &status); - rpc_unmarshal_long(rpc, granted); - rpc_unmarshal_long(rpc, fid); - - rpc_destroy(rpc); - TIMING_END("create"); - return status; - } +{ + rpc_t *rpc; + ULONG status; + TIMING_START(); + + rpc = rpc_create(0); + + rpc_marshal_long(rpc, RPC_CREATE); + rpc_marshal_long(rpc, attribs); + rpc_marshal_longlong(rpc, alloc); + rpc_marshal_long(rpc, access); + + rpc_queue_bulk(rpc, (void*)name, (wcslen(name)+1)*sizeof(wchar_t), NULL, 0); + if (!rpc_wait(rpc, RPC_TIMEOUT_SHORT)) + { + rpc_cancel(rpc); + rpt0(("cancel", "cancel create")); + return IFSL_RPC_TIMEOUT; + } + + rpc_unmarshal_long(rpc, &status); + rpc_unmarshal_long(rpc, granted); + rpc_unmarshal_long(rpc, fid); + + rpc_destroy(rpc); + TIMING_END("create"); + return status; +} uc_stat(ULONG fid, ULONG *attribs, LARGE_INTEGER *size, LARGE_INTEGER *creation, LARGE_INTEGER *access, LARGE_INTEGER *change, LARGE_INTEGER *written) - { - rpc_t *rpc; - ULONG status; - TIMING_START(); - - rpc = rpc_create(0); - - rpc_marshal_long(rpc, RPC_STAT); - rpc_marshal_long(rpc, fid); - - rpc_queue(rpc); - if (!rpc_wait(rpc, RPC_TIMEOUT_SHORT)) - { - rpc_cancel(rpc); - rpt0(("cancel", "cancel stat")); - return IFSL_RPC_TIMEOUT; - } - - rpc_unmarshal_long(rpc, &status); - rpc_unmarshal_long(rpc, attribs); - rpc_unmarshal_longlong(rpc, size); - rpc_unmarshal_longlong(rpc, creation); - rpc_unmarshal_longlong(rpc, access); - rpc_unmarshal_longlong(rpc, change); - rpc_unmarshal_longlong(rpc, written); - - rpc_destroy(rpc); - TIMING_END("stat"); - return status; - } +{ + rpc_t *rpc; + ULONG status; + TIMING_START(); + + rpc = rpc_create(0); + + rpc_marshal_long(rpc, RPC_STAT); + rpc_marshal_long(rpc, fid); + + rpc_queue(rpc); + if (!rpc_wait(rpc, RPC_TIMEOUT_SHORT)) + { + rpc_cancel(rpc); + rpt0(("cancel", "cancel stat")); + return IFSL_RPC_TIMEOUT; + } + + rpc_unmarshal_long(rpc, &status); + rpc_unmarshal_long(rpc, attribs); + rpc_unmarshal_longlong(rpc, size); + rpc_unmarshal_longlong(rpc, creation); + rpc_unmarshal_longlong(rpc, access); + rpc_unmarshal_longlong(rpc, change); + rpc_unmarshal_longlong(rpc, written); + + rpc_destroy(rpc); + TIMING_END("stat"); + return status; +} uc_setinfo(ULONG fid, ULONG attribs, LARGE_INTEGER creation, LARGE_INTEGER access, LARGE_INTEGER change, LARGE_INTEGER written) - { - rpc_t *rpc; - ULONG status; - TIMING_START(); +{ + rpc_t *rpc; + ULONG status; + TIMING_START(); - rpc = rpc_create(0); + rpc = rpc_create(0); - rpc_marshal_long(rpc, RPC_SETINFO); - rpc_marshal_long(rpc, fid); - rpc_marshal_long(rpc, attribs); - rpc_marshal_longlong(rpc, creation); - rpc_marshal_longlong(rpc, access); - rpc_marshal_longlong(rpc, change); - rpc_marshal_longlong(rpc, written); + rpc_marshal_long(rpc, RPC_SETINFO); + rpc_marshal_long(rpc, fid); + rpc_marshal_long(rpc, attribs); + rpc_marshal_longlong(rpc, creation); + rpc_marshal_longlong(rpc, access); + rpc_marshal_longlong(rpc, change); + rpc_marshal_longlong(rpc, written); - rpc_queue(rpc); - if (!rpc_wait(rpc, RPC_TIMEOUT_SHORT)) - { - rpc_cancel(rpc); - rpt0(("cancel", "cancel setinfo")); - return IFSL_RPC_TIMEOUT; - } + rpc_queue(rpc); + if (!rpc_wait(rpc, RPC_TIMEOUT_SHORT)) + { + rpc_cancel(rpc); + rpt0(("cancel", "cancel setinfo")); + return IFSL_RPC_TIMEOUT; + } - rpc_unmarshal_long(rpc, &status); + rpc_unmarshal_long(rpc, &status); - rpc_destroy(rpc); - TIMING_END("setinfo"); - return status; - } + rpc_destroy(rpc); + TIMING_END("setinfo"); + return status; +} uc_trunc(ULONG fid, LARGE_INTEGER size) - { - rpc_t *rpc; - ULONG status; - TIMING_START(); +{ + rpc_t *rpc; + ULONG status; + TIMING_START(); - rpc = rpc_create(0); + rpc = rpc_create(0); - rpc_marshal_long(rpc, RPC_TRUNC); - rpc_marshal_long(rpc, fid); - rpc_marshal_longlong(rpc, size); + rpc_marshal_long(rpc, RPC_TRUNC); + rpc_marshal_long(rpc, fid); + rpc_marshal_longlong(rpc, size); - rpc_queue(rpc); - if (!rpc_wait(rpc, RPC_TIMEOUT_SHORT)) - { - rpc_cancel(rpc); - rpt0(("cancel", "cancel trunc")); - return IFSL_RPC_TIMEOUT; - } + rpc_queue(rpc); + if (!rpc_wait(rpc, RPC_TIMEOUT_SHORT)) + { + rpc_cancel(rpc); + rpt0(("cancel", "cancel trunc")); + return IFSL_RPC_TIMEOUT; + } - rpc_unmarshal_long(rpc, &status); + rpc_unmarshal_long(rpc, &status); - rpc_destroy(rpc); - TIMING_END("trunc"); - return status; - } + rpc_destroy(rpc); + TIMING_END("trunc"); + return status; +} uc_read(ULONG fid, LARGE_INTEGER offset, ULONG length, ULONG *read, char *data) - { - rpc_t *rpc; - ULONG status; - TIMING_START(); - - rpc = rpc_create(0); - - rpc_marshal_long(rpc, RPC_READ); - rpc_marshal_long(rpc, fid); - rpc_marshal_longlong(rpc, offset); - rpc_marshal_long(rpc, length); - - rpc_queue_bulk(rpc, NULL, 0, data, length); - if (!rpc_wait(rpc, RPC_TIMEOUT_LONG)) - { - rpc_cancel(rpc); - rpt0(("cancel", "cancel read")); - return IFSL_RPC_TIMEOUT; - } - - rpc_unmarshal_long(rpc, &status); - rpc_unmarshal_long(rpc, read); - - rpc_destroy(rpc); - TIMING_END("read"); - return status; - } +{ + rpc_t *rpc; + ULONG status; + TIMING_START(); + + rpc = rpc_create(0); + + rpc_marshal_long(rpc, RPC_READ); + rpc_marshal_long(rpc, fid); + rpc_marshal_longlong(rpc, offset); + rpc_marshal_long(rpc, length); + + rpc_queue_bulk(rpc, NULL, 0, data, length); + if (!rpc_wait(rpc, RPC_TIMEOUT_LONG)) + { + rpc_cancel(rpc); + rpt0(("cancel", "cancel read")); + return IFSL_RPC_TIMEOUT; + } + + rpc_unmarshal_long(rpc, &status); + rpc_unmarshal_long(rpc, read); + + rpc_destroy(rpc); + TIMING_END("read"); + return status; +} /*uc_read_mdl(ULONG fid, LARGE_INTEGER offset, ULONG length, ULONG *read, MDL *data) - { - rpc_t *rpc; - ULONG status; - TIMING_START(); - - rpc = rpc_create(0); - - rpc_marshal_long(rpc, RPC_READ_BULK); - rpc_marshal_long(rpc, fid); - rpc_marshal_longlong(rpc, offset); - rpc_marshal_long(rpc, length); - - rpc_queue_bulk_mdl(rpc, data); - if (!rpc_wait(rpc, 1)) - { - rpc_cancel(rpc); - rpt0(("cancel", "cancel read mdl")); - return IFSL_RPC_TIMEOUT; - } - - rpc_unmarshal_long(rpc, &status); - rpc_unmarshal_long(rpc, read); - - rpc_destroy(rpc); - TIMING_END("read_mdl"); - return status; - }*/ +{ + rpc_t *rpc; + ULONG status; + TIMING_START(); + + rpc = rpc_create(0); + + rpc_marshal_long(rpc, RPC_READ_BULK); + rpc_marshal_long(rpc, fid); + rpc_marshal_longlong(rpc, offset); + rpc_marshal_long(rpc, length); + + rpc_queue_bulk_mdl(rpc, data); + if (!rpc_wait(rpc, 1)) + { + rpc_cancel(rpc); + rpt0(("cancel", "cancel read mdl")); + return IFSL_RPC_TIMEOUT; + } + + rpc_unmarshal_long(rpc, &status); + rpc_unmarshal_long(rpc, read); + + rpc_destroy(rpc); + TIMING_END("read_mdl"); + return status; +}*/ uc_write(ULONG fid, LARGE_INTEGER offset, ULONG length, ULONG *written, char *data) - { - rpc_t *rpc; - ULONG status; - TIMING_START(); - - rpc = rpc_create(0); - - rpc_marshal_long(rpc, RPC_WRITE); - rpc_marshal_long(rpc, fid); - rpc_marshal_longlong(rpc, offset); - rpc_marshal_long(rpc, length); - - rpc_queue_bulk(rpc, data, length, NULL, 0); - if (!rpc_wait(rpc, RPC_TIMEOUT_LONG)) - { - rpc_cancel(rpc); - rpt0(("cancel", "cancel write")); - return IFSL_RPC_TIMEOUT; - } - - rpc_unmarshal_long(rpc, &status); - rpc_unmarshal_long(rpc, written); - - rpc_destroy(rpc); - TIMING_END("write"); - return status; - } +{ + rpc_t *rpc; + ULONG status; + TIMING_START(); + + rpc = rpc_create(0); + + rpc_marshal_long(rpc, RPC_WRITE); + rpc_marshal_long(rpc, fid); + rpc_marshal_longlong(rpc, offset); + rpc_marshal_long(rpc, length); + + rpc_queue_bulk(rpc, data, length, NULL, 0); + if (!rpc_wait(rpc, RPC_TIMEOUT_LONG)) + { + rpc_cancel(rpc); + rpt0(("cancel", "cancel write")); + return IFSL_RPC_TIMEOUT; + } + + rpc_unmarshal_long(rpc, &status); + rpc_unmarshal_long(rpc, written); + + rpc_destroy(rpc); + TIMING_END("write"); + return status; +} /*uc_write_mdl(ULONG fid, LARGE_INTEGER offset, ULONG length, ULONG *written, MDL *data) - { - rpc_t *rpc; - ULONG status; - TIMING_START(); - - rpc = rpc_create(0); - - rpc_marshal_long(rpc, RPC_WRITE_BULK); - rpc_marshal_long(rpc, fid); - rpc_marshal_longlong(rpc, offset); - rpc_marshal_long(rpc, length); - - rpc_queue_bulk_mdl(rpc, data); - if (!rpc_wait(rpc, 1)) - { - rpc_cancel(rpc); - rpt0(("cancel", "cancel write mdl")); - return IFSL_RPC_TIMEOUT; - } - - rpc_unmarshal_long(rpc, &status); - rpc_unmarshal_long(rpc, written); - - rpc_destroy(rpc); - TIMING_END("write_mdl"); - return status; - }*/ +{ + rpc_t *rpc; + ULONG status; + TIMING_START(); + + rpc = rpc_create(0); + + rpc_marshal_long(rpc, RPC_WRITE_BULK); + rpc_marshal_long(rpc, fid); + rpc_marshal_longlong(rpc, offset); + rpc_marshal_long(rpc, length); + + rpc_queue_bulk_mdl(rpc, data); + if (!rpc_wait(rpc, 1)) + { + rpc_cancel(rpc); + rpt0(("cancel", "cancel write mdl")); + return IFSL_RPC_TIMEOUT; + } + + rpc_unmarshal_long(rpc, &status); + rpc_unmarshal_long(rpc, written); + + rpc_destroy(rpc); + TIMING_END("write_mdl"); + return status; +}*/ uc_readdir(ULONG fid, LARGE_INTEGER cookie_in, WCHAR *filter, ULONG *count, char *data, ULONG *len) - { - rpc_t *rpc; - ULONG status; - TIMING_START(); - - rpc = rpc_create(0); - - rpc_marshal_long(rpc, RPC_READDIR); - rpc_marshal_long(rpc, fid); - rpc_marshal_longlong(rpc, cookie_in); - rpc_marshal_wstr(rpc, filter); - rpc_marshal_long(rpc, *len); - - rpc_queue_bulk(rpc, NULL, 0, data, *len); - if (!rpc_wait(rpc, RPC_TIMEOUT_SHORT)) - { - rpc_cancel(rpc); - rpt0(("cancel", "cancel readdir")); - return IFSL_RPC_TIMEOUT; - } - - rpc_unmarshal_long(rpc, &status); - rpc_unmarshal_long(rpc, count); - rpc_unmarshal_long(rpc, len); - - rpc_destroy(rpc); - TIMING_END("readdir"); - return status; - } +{ + rpc_t *rpc; + ULONG status; + TIMING_START(); + + rpc = rpc_create(0); + + rpc_marshal_long(rpc, RPC_READDIR); + rpc_marshal_long(rpc, fid); + rpc_marshal_longlong(rpc, cookie_in); + rpc_marshal_wstr(rpc, filter); + rpc_marshal_long(rpc, *len); + + rpc_queue_bulk(rpc, NULL, 0, data, *len); + if (!rpc_wait(rpc, RPC_TIMEOUT_SHORT)) + { + rpc_cancel(rpc); + rpt0(("cancel", "cancel readdir")); + return IFSL_RPC_TIMEOUT; + } + + rpc_unmarshal_long(rpc, &status); + rpc_unmarshal_long(rpc, count); + rpc_unmarshal_long(rpc, len); + + rpc_destroy(rpc); + TIMING_END("readdir"); + return status; +} uc_close(ULONG fid) - { - rpc_t *rpc; - ULONG status; - TIMING_START(); +{ + rpc_t *rpc; + ULONG status; + TIMING_START(); - rpc = rpc_create(0); + rpc = rpc_create(0); - rpc_marshal_long(rpc, RPC_CLOSE); - rpc_marshal_long(rpc, fid); + rpc_marshal_long(rpc, RPC_CLOSE); + rpc_marshal_long(rpc, fid); - rpc_queue(rpc); - if (!rpc_wait(rpc, RPC_TIMEOUT_LONG)) - { - rpc_cancel(rpc); - rpt0(("cancel", "cancel close")); - return IFSL_RPC_TIMEOUT; - } + rpc_queue(rpc); + if (!rpc_wait(rpc, RPC_TIMEOUT_LONG)) + { + rpc_cancel(rpc); + rpt0(("cancel", "cancel close")); + return IFSL_RPC_TIMEOUT; + } - rpc_unmarshal_long(rpc, &status); + rpc_unmarshal_long(rpc, &status); - rpc_destroy(rpc); - TIMING_END("close"); - return status; - } + rpc_destroy(rpc); + TIMING_END("close"); + return status; +} uc_unlink(WCHAR *name) - { - rpc_t *rpc; - ULONG status; - TIMING_START(); +{ + rpc_t *rpc; + ULONG status; + TIMING_START(); - rpc = rpc_create(0); + rpc = rpc_create(0); - rpc_marshal_long(rpc, RPC_UNLINK); - rpc_marshal_wstr(rpc, name); + rpc_marshal_long(rpc, RPC_UNLINK); + rpc_marshal_wstr(rpc, name); - rpc_queue(rpc); - if (!rpc_wait(rpc, RPC_TIMEOUT_SHORT)) - { - rpc_cancel(rpc); - rpt0(("cancel", "cancel unlink")); - return IFSL_RPC_TIMEOUT; - } + rpc_queue(rpc); + if (!rpc_wait(rpc, RPC_TIMEOUT_SHORT)) + { + rpc_cancel(rpc); + rpt0(("cancel", "cancel unlink")); + return IFSL_RPC_TIMEOUT; + } - rpc_unmarshal_long(rpc, &status); + rpc_unmarshal_long(rpc, &status); - rpc_destroy(rpc); - TIMING_END("unlink"); - return status; - } + rpc_destroy(rpc); + TIMING_END("unlink"); + return status; +} uc_ioctl_write(ULONG length, char *data, ULONG *key) - { - rpc_t *rpc; - ULONG status; - TIMING_START(); +{ + rpc_t *rpc; + ULONG status; + TIMING_START(); - rpc = rpc_create(0); + rpc = rpc_create(0); - rpc_marshal_long(rpc, RPC_IOCTL_WRITE); - rpc_marshal_long(rpc, length); + rpc_marshal_long(rpc, RPC_IOCTL_WRITE); + rpc_marshal_long(rpc, length); - rpc_queue_bulk(rpc, data, length, NULL, 0); - if (!rpc_wait(rpc, RPC_TIMEOUT_SHORT)) - { - rpc_cancel(rpc); - rpt0(("cancel", "cancel ioctl write")); - return IFSL_RPC_TIMEOUT; - } + rpc_queue_bulk(rpc, data, length, NULL, 0); + if (!rpc_wait(rpc, RPC_TIMEOUT_SHORT)) + { + rpc_cancel(rpc); + rpt0(("cancel", "cancel ioctl write")); + return IFSL_RPC_TIMEOUT; + } - rpc_unmarshal_long(rpc, &status); - rpc_unmarshal_long(rpc, key); + rpc_unmarshal_long(rpc, &status); + rpc_unmarshal_long(rpc, key); - rpc_destroy(rpc); - TIMING_END("ioctl_write"); - return status; - } + rpc_destroy(rpc); + TIMING_END("ioctl_write"); + return status; +} uc_ioctl_read(ULONG key, ULONG *length, char *data) - { - rpc_t *rpc; - ULONG status; - TIMING_START(); +{ + rpc_t *rpc; + ULONG status; + TIMING_START(); - rpc = rpc_create(0); + rpc = rpc_create(0); - rpc_marshal_long(rpc, RPC_IOCTL_READ); - rpc_marshal_long(rpc, key); + rpc_marshal_long(rpc, RPC_IOCTL_READ); + rpc_marshal_long(rpc, key); - rpc_queue_bulk(rpc, NULL, 0, data, *length); - if (!rpc_wait(rpc, RPC_TIMEOUT_SHORT)) - { - rpc_cancel(rpc); - rpt0(("cancel", "cancel ioctl read")); - return IFSL_RPC_TIMEOUT; - } + rpc_queue_bulk(rpc, NULL, 0, data, *length); + if (!rpc_wait(rpc, RPC_TIMEOUT_SHORT)) + { + rpc_cancel(rpc); + rpt0(("cancel", "cancel ioctl read")); + return IFSL_RPC_TIMEOUT; + } - rpc_unmarshal_long(rpc, &status); - rpc_unmarshal_long(rpc, length); + rpc_unmarshal_long(rpc, &status); + rpc_unmarshal_long(rpc, length); - rpc_destroy(rpc); - TIMING_END("ioctl_read"); - return status; - } + rpc_destroy(rpc); + TIMING_END("ioctl_read"); + return status; +} uc_rename(ULONG fid, WCHAR *curr, WCHAR *new_dir, WCHAR *new_name, ULONG *new_fid) - { - rpc_t *rpc; - ULONG status; - TIMING_START(); - - rpc = rpc_create(0); - - rpc_marshal_long(rpc, RPC_RENAME); - rpc_marshal_long(rpc, fid); - rpc_marshal_wstr(rpc, curr); - rpc_marshal_wstr(rpc, new_dir); - rpc_marshal_wstr(rpc, new_name); - - rpc_queue(rpc); - if (!rpc_wait(rpc, RPC_TIMEOUT_SHORT)) - { - rpc_cancel(rpc); - rpt0(("cancel", "cancel rename")); - return IFSL_RPC_TIMEOUT; - } - - rpc_unmarshal_long(rpc, &status); - rpc_unmarshal_long(rpc, new_fid); - - rpc_destroy(rpc); - TIMING_END("rename"); - return status; - } +{ + rpc_t *rpc; + ULONG status; + TIMING_START(); + + rpc = rpc_create(0); + + rpc_marshal_long(rpc, RPC_RENAME); + rpc_marshal_long(rpc, fid); + rpc_marshal_wstr(rpc, curr); + rpc_marshal_wstr(rpc, new_dir); + rpc_marshal_wstr(rpc, new_name); + + rpc_queue(rpc); + if (!rpc_wait(rpc, RPC_TIMEOUT_SHORT)) + { + rpc_cancel(rpc); + rpt0(("cancel", "cancel rename")); + return IFSL_RPC_TIMEOUT; + } + + rpc_unmarshal_long(rpc, &status); + rpc_unmarshal_long(rpc, new_fid); + + rpc_destroy(rpc); + TIMING_END("rename"); + return status; +} #endif /* downcall stubs */ #ifndef RPC_KERN dc_break_callback(ULONG fid) - { - rpc_t *rpc; - ULONG status; - - rpc = rpc_create(0); - - rpc_marshal_long(rpc, RPC_BREAK_CALLBACK); - rpc_marshal_long(rpc, fid); - if (!rpc_transact(rpc)) - { - rpc_destroy(rpc); - return IFSL_GENERIC_FAILURE; - } - rpc_unmarshal_long(rpc, &status); - rpc_destroy(rpc); - return status; - } +{ + rpc_t *rpc; + ULONG status; + + rpc = rpc_create(0); + + rpc_marshal_long(rpc, RPC_BREAK_CALLBACK); + rpc_marshal_long(rpc, fid); + if (!rpc_transact(rpc)) + { + rpc_destroy(rpc); + return IFSL_GENERIC_FAILURE; + } + rpc_unmarshal_long(rpc, &status); + rpc_destroy(rpc); + return status; +} #endif /* rpc packing function */ rpc_marshal_long(rpc_t *rpc, ULONG data) - { - memcpy(rpc->out_pos, &data, sizeof(ULONG)); - rpc->out_pos += sizeof(ULONG); - return 0; - } +{ + memcpy(rpc->out_pos, &data, sizeof(ULONG)); + rpc->out_pos += sizeof(ULONG); + return 0; +} rpc_marshal_longlong(rpc_t *rpc, LARGE_INTEGER data) - { - memcpy(rpc->out_pos, &data, sizeof(LARGE_INTEGER)); - rpc->out_pos += sizeof(LARGE_INTEGER); - return 0; - } +{ + memcpy(rpc->out_pos, &data, sizeof(LARGE_INTEGER)); + rpc->out_pos += sizeof(LARGE_INTEGER); + return 0; +} rpc_marshal_wstr(rpc_t *rpc, WCHAR *str) - { - long len; - len = wcslen(str); - rpc_marshal_long(rpc, len); - memcpy(rpc->out_pos, str, len*sizeof(WCHAR)); - rpc->out_pos += len*sizeof(WCHAR); - return 0; - } +{ + long len; + len = wcslen(str); + rpc_marshal_long(rpc, len); + memcpy(rpc->out_pos, str, len*sizeof(WCHAR)); + rpc->out_pos += len*sizeof(WCHAR); + return 0; +} rpc_unmarshal_long(rpc_t *rpc, ULONG *data) - { - memcpy(data, rpc->in_pos, sizeof(ULONG)); - rpc->in_pos += sizeof(ULONG); - return 0; - } +{ + memcpy(data, rpc->in_pos, sizeof(ULONG)); + rpc->in_pos += sizeof(ULONG); + return 0; +} rpc_unmarshal_longlong(rpc_t *rpc, LARGE_INTEGER *data) - { - memcpy(data, rpc->in_pos, sizeof(LARGE_INTEGER)); - rpc->in_pos += sizeof(LARGE_INTEGER); - return 0; - } +{ + memcpy(data, rpc->in_pos, sizeof(LARGE_INTEGER)); + rpc->in_pos += sizeof(LARGE_INTEGER); + return 0; +} rpc_unmarshal_wstr(rpc_t *rpc, WCHAR *str)//, int len) - { - long len; - rpc_unmarshal_long(rpc, &len); - memcpy(str, rpc->in_pos, len*sizeof(WCHAR)); - rpc->in_pos += len*sizeof(WCHAR); - str[len] = L'\0'; - return 0; - } +{ + long len; + rpc_unmarshal_long(rpc, &len); + memcpy(str, rpc->in_pos, len*sizeof(WCHAR)); + rpc->in_pos += len*sizeof(WCHAR); + str[len] = L'\0'; + return 0; +} /* kernel-queue management functions */ #ifdef RPC_KERN rpc_t *rpc_find(int id) - { - rpc_t *curr; - - curr = rpc_list_head; - while (curr) - { - if (curr->key == id && curr->status != 0) - return curr; - curr = curr->next; - } - return NULL; - } +{ + rpc_t *curr; + + curr = rpc_list_head; + while (curr) + { + if (curr->key == id && curr->status != 0) + return curr; + curr = curr->next; + } + return NULL; +} rpc_t *rpc_upgrade(rpc_t *rpc, int old_status, int new_status) - { - rpc_t *curr; - - if (rpc) - { - ASSERT(!old_status || rpc_find(rpc->key)); - if (old_status != -1 && rpc->status != old_status) - return NULL; - curr = rpc; - } - else - { - curr = rpc_list_head; - while (curr) - { - if (old_status == -1 || curr->status == old_status) - break; - curr = curr->next; - } - } - - if (!curr) - return NULL; - - ASSERT(old_status == -1 || curr->status == old_status); - curr->status = new_status; - - return curr; - } +{ + rpc_t *curr; + + if (rpc) + { + ASSERT(!old_status || rpc_find(rpc->key)); + if (old_status != -1 && rpc->status != old_status) + return NULL; + curr = rpc; + } + else + { + curr = rpc_list_head; + while (curr) + { + if (old_status == -1 || curr->status == old_status) + break; + curr = curr->next; + } + } + + if (!curr) + return NULL; + + ASSERT(old_status == -1 || curr->status == old_status); + curr->status = new_status; + + return curr; +} rpc_queue(rpc_t *rpc) - { - int ret; +{ + int ret; - ifs_lock_rpcs(); + ifs_lock_rpcs(); - KeInitializeEvent(&rpc->ev, NotificationEvent, FALSE); - ret = (rpc_upgrade(rpc, 1, 2) != NULL); - KeSetEvent(&comExt->outEvent, 0, FALSE); + KeInitializeEvent(&rpc->ev, NotificationEvent, FALSE); + ret = (rpc_upgrade(rpc, 1, 2) != NULL); + KeSetEvent(&comExt->outEvent, 0, FALSE); - ifs_unlock_rpcs(); + ifs_unlock_rpcs(); - return ret; - } + return ret; +} rpc_cancel(rpc_t *rpc) - { - rpc_destroy(rpc); - //ExAcquireFastMutex(&ext->inLock); - /*ifs_lock_rpcs(); - if (rpc_upgrade(rpc, -1, 0)) - rpc_destroy(rpc); - ifs_unlock_rpcs();*/ - //RtlDeleteElementGenericTable(&ext->inTable, (void*)&rpc); - //ExReleaseFastMutex(&ext->inLock); - } +{ + rpc_destroy(rpc); + //ExAcquireFastMutex(&ext->inLock); + /*ifs_lock_rpcs(); + if (rpc_upgrade(rpc, -1, 0)) + rpc_destroy(rpc); + ifs_unlock_rpcs();*/ + //RtlDeleteElementGenericTable(&ext->inTable, (void*)&rpc); + //ExReleaseFastMutex(&ext->inLock); +} rpc_shutdown() - { - rpc_t *curr, *next; +{ + rpc_t *curr, *next; - ifs_lock_rpcs(); + ifs_lock_rpcs(); - curr = rpc_list_head; - while (curr) - { - next = curr->next; - ExFreePoolWithTag(curr, 0x1234); - curr = next; - } - rpc_list_head = NULL; + curr = rpc_list_head; + while (curr) + { + next = curr->next; + ExFreePoolWithTag(curr, 0x1234); + curr = next; + } + rpc_list_head = NULL; - ifs_unlock_rpcs(); - } + ifs_unlock_rpcs(); +} rpc_wait(rpc_t *rpc, BOOLEAN long_op) - { - NTSTATUS ret; - LARGE_INTEGER timeout; - //p->FsContext = (ULONG)&ev; - - if (long_op) - timeout.QuadPart = -600000000L; /* 60 seconds 60L*1000000L */ - else - timeout.QuadPart = -200000000L; /* 20 seconds 20L*1000000L */ - - do - ret = KeWaitForSingleObject(&rpc->ev, Executive, KernelMode, FALSE, &timeout); - while (ret != STATUS_SUCCESS);// && ret != STATUS_TIMEOUT); - - /*if (KeReadStateEvent(&rpc->ev) == 0) - _asm int 3;*/ - if (rpc->status == 5) - return 0; - - if (ret == STATUS_SUCCESS) - return 1; - _asm int 3; - return 0; - } +{ + NTSTATUS ret; + LARGE_INTEGER timeout; + //p->FsContext = (ULONG)&ev; + + if (long_op) + timeout.QuadPart = -600000000L; /* 60 seconds 60L*1000000L */ + else + timeout.QuadPart = -200000000L; /* 20 seconds 20L*1000000L */ + + do + ret = KeWaitForSingleObject(&rpc->ev, Executive, KernelMode, FALSE, &timeout); + while (ret != STATUS_SUCCESS);// && ret != STATUS_TIMEOUT); + + /*if (KeReadStateEvent(&rpc->ev) == 0) + _asm int 3;*/ + if (rpc->status == 5) + return 0; + + if (ret == STATUS_SUCCESS) + return 1; + _asm int 3; + return 0; +} rpc_queue_bulk(rpc_t *rpc, char *out_bulk, ULONG out_len, char *in_bulk, ULONG in_len) - { - rpc->bulk_out = out_bulk; - *rpc->bulk_out_len = out_len; - rpc->bulk_in = in_bulk; - rpc->bulk_in_max = in_len; - return rpc_queue(rpc); - } +{ + rpc->bulk_out = out_bulk; + *rpc->bulk_out_len = out_len; + rpc->bulk_in = in_bulk; + rpc->bulk_in_max = in_len; + return rpc_queue(rpc); +} /*rpc_queue_bulk_mdl(rpc_t *rpc, MDL *bulk) - { - rpc->bulk_mdl = bulk; - *rpc->bulk_out_len = 0xFFFFFFFC; - rpc->bulk_in = 0; - return rpc_queue(rpc); - }*/ +{ + rpc->bulk_mdl = bulk; + *rpc->bulk_out_len = 0xFFFFFFFC; + rpc->bulk_in = 0; + return rpc_queue(rpc); +}*/ rpc_get_len(rpc_t *rpc) - { - if (*rpc->bulk_out_len != 0xFFFFFFFC) - return rpc->out_pos - rpc->out_buf + *rpc->bulk_out_len + sizeof(ULONG); - else - return rpc->out_pos - rpc->out_buf + sizeof(ULONG); - } +{ + if (*rpc->bulk_out_len != 0xFFFFFFFC) + return rpc->out_pos - rpc->out_buf + *rpc->bulk_out_len + sizeof(ULONG); + else + return rpc->out_pos - rpc->out_buf + sizeof(ULONG); +} rpc_send(char *out_buf, int out_len, int *out_written) - { - rpc_t *rpc; - int ret, mdl; - ULONG header_len; - - restart: - - ifs_lock_rpcs(); - rpc = rpc_upgrade(NULL, 2, 3); - - if (!rpc) - { - ifs_unlock_rpcs(); - return 0; - } - - if (rpc_get_len(rpc) > out_len) - { - //_asm int 3; - ifs_unlock_rpcs(); - rpt0(("cancel", "cancel on send")); - rpc_upgrade(rpc, -1, 5); - KeSetEvent(&rpc->ev, IO_NO_INCREMENT, FALSE); /* move to rpc_ fn */ - //rpc_cancel(rpc); - goto restart;//return 0; - } - - - - /*mdl = (*rpc->bulk_out_len == 0xFFFFFFFC); - - if (mdl) - *rpc->bulk_out_len = 0;*/ - - header_len = rpc->out_pos - rpc->out_buf; - RtlCopyMemory(out_buf, rpc->out_buf, header_len); - - //if (!mdl) - { - if (*rpc->bulk_out_len && rpc->bulk_out) - RtlCopyMemory(out_buf + header_len, rpc->bulk_out, *rpc->bulk_out_len); - *out_written = header_len + *rpc->bulk_out_len; - } - #if 0 - else - { - if (rpc->bulk_mdl) - { - void *ptr; - //_asm int 3; - #if 0 - try - { - _asm int 3; - MmProbeAndLockPages(rpc->bulk_mdl, UserMode, IoModifyAccess); - } - except (EXCEPTION_EXECUTE_HANDLER) - { - _asm int 3; - } - #endif - try - { - rpc->bulk_out = MmMapLockedPagesSpecifyCache(rpc->bulk_mdl, UserMode, MmNonCached, NULL, FALSE, NormalPagePriority); - } - except (EXCEPTION_EXECUTE_HANDLER) - { - PMDL remap; - void *ptr; - _asm int 3; - ptr = ExAllocatePool(PagedPool, MmGetMdlByteCount(rpc->bulk_mdl)); - remap = IoAllocateMdl(ptr, MmGetMdlByteCount(rpc->bulk_mdl), FALSE, TRUE, NULL); - MmProbeAndLockPages(remap, UserMode, IoModifyAccess); - rpc->bulk_out = MmMapLockedPagesSpecifyCache(remap, KernelMode, MmNonCached, NULL, FALSE, NormalPagePriority); - _asm int 3; - rpc->bulk_out = MmGetSystemAddressForMdlSafe(rpc->bulk_mdl, NormalPagePriority); - MmUnmapLockedPages(rpc->bulk_out, rpc->bulk_mdl); - rpc->bulk_out = MmMapLockedPagesSpecifyCache(rpc->bulk_mdl, UserMode, MmNonCached, NULL, FALSE, NormalPagePriority); - - remap = IoAllocateMdl(rpc->bulk_out, MmGetMdlByteCount(rpc->bulk_mdl), FALSE, TRUE, NULL); - remap->Process = (void*)PsGetCurrentProcess(); - MmBuildMdlForNonPagedPool(remap); - //MmProbeAndLockPages(remap, UserMode, IoModifyAccess); - rpc->bulk_out = MmMapLockedPagesSpecifyCache(remap, UserMode, MmNonCached, (void*)0x01111111, FALSE, NormalPagePriority); - /*ifs_unlock_rpcs(); - rpc_upgrade(rpc, -1, 5); - KeSetEvent(&rpc->ev, IO_NO_INCREMENT, FALSE); - //rpc_cancel(rpc); - goto restart;//return 0;*/ - } - ptr = rpc->bulk_out; - RtlCopyMemory(out_buf + header_len, &ptr, sizeof(ptr)); - } - - *rpc->bulk_out_len = 0xFFFFFFFC; - *out_written = header_len + sizeof(void*); - } - #endif - - ifs_unlock_rpcs(); - return (*out_written != 0); - } +{ + rpc_t *rpc; + int ret, mdl; + ULONG header_len; + + restart: + + ifs_lock_rpcs(); + rpc = rpc_upgrade(NULL, 2, 3); + + if (!rpc) + { + ifs_unlock_rpcs(); + return 0; + } + + if (rpc_get_len(rpc) > out_len) + { + //_asm int 3; + ifs_unlock_rpcs(); + rpt0(("cancel", "cancel on send")); + rpc_upgrade(rpc, -1, 5); + KeSetEvent(&rpc->ev, IO_NO_INCREMENT, FALSE); /* move to rpc_ fn */ + //rpc_cancel(rpc); + goto restart;//return 0; + } + + + + /*mdl = (*rpc->bulk_out_len == 0xFFFFFFFC); + + if (mdl) + *rpc->bulk_out_len = 0;*/ + + header_len = rpc->out_pos - rpc->out_buf; + RtlCopyMemory(out_buf, rpc->out_buf, header_len); + + //if (!mdl) + { + if (*rpc->bulk_out_len && rpc->bulk_out) + RtlCopyMemory(out_buf + header_len, rpc->bulk_out, *rpc->bulk_out_len); + *out_written = header_len + *rpc->bulk_out_len; + } +#if 0 + else + { + if (rpc->bulk_mdl) + { + void *ptr; + //_asm int 3; +#if 0 + try + { + _asm int 3; + MmProbeAndLockPages(rpc->bulk_mdl, UserMode, IoModifyAccess); + } + except (EXCEPTION_EXECUTE_HANDLER) + { + _asm int 3; + } +#endif + try + { + rpc->bulk_out = MmMapLockedPagesSpecifyCache(rpc->bulk_mdl, UserMode, MmNonCached, NULL, FALSE, NormalPagePriority); + } + except (EXCEPTION_EXECUTE_HANDLER) + { + PMDL remap; + void *ptr; + _asm int 3; + ptr = ExAllocatePool(PagedPool, MmGetMdlByteCount(rpc->bulk_mdl)); + remap = IoAllocateMdl(ptr, MmGetMdlByteCount(rpc->bulk_mdl), FALSE, TRUE, NULL); + MmProbeAndLockPages(remap, UserMode, IoModifyAccess); + rpc->bulk_out = MmMapLockedPagesSpecifyCache(remap, KernelMode, MmNonCached, NULL, FALSE, NormalPagePriority); + _asm int 3; + rpc->bulk_out = MmGetSystemAddressForMdlSafe(rpc->bulk_mdl, NormalPagePriority); + MmUnmapLockedPages(rpc->bulk_out, rpc->bulk_mdl); + rpc->bulk_out = MmMapLockedPagesSpecifyCache(rpc->bulk_mdl, UserMode, MmNonCached, NULL, FALSE, NormalPagePriority); + + remap = IoAllocateMdl(rpc->bulk_out, MmGetMdlByteCount(rpc->bulk_mdl), FALSE, TRUE, NULL); + remap->Process = (void*)PsGetCurrentProcess(); + MmBuildMdlForNonPagedPool(remap); + //MmProbeAndLockPages(remap, UserMode, IoModifyAccess); + rpc->bulk_out = MmMapLockedPagesSpecifyCache(remap, UserMode, MmNonCached, (void*)0x01111111, FALSE, NormalPagePriority); + /*ifs_unlock_rpcs(); + rpc_upgrade(rpc, -1, 5); + KeSetEvent(&rpc->ev, IO_NO_INCREMENT, FALSE); + //rpc_cancel(rpc); + goto restart;//return 0;*/ + } + ptr = rpc->bulk_out; + RtlCopyMemory(out_buf + header_len, &ptr, sizeof(ptr)); + } + + *rpc->bulk_out_len = 0xFFFFFFFC; + *out_written = header_len + sizeof(void*); + } +#endif + + ifs_unlock_rpcs(); + return (*out_written != 0); +} #if 0 rpc_send_reg(rpc_t *rpc, char *out_buf) - { - ULONG header_len; +{ + ULONG header_len; - header_len = rpc->out_pos - rpc->out_buf; - RtlCopyMemory(out_buf, rpc->out_buf, header_len); + header_len = rpc->out_pos - rpc->out_buf; + RtlCopyMemory(out_buf, rpc->out_buf, header_len); - if (rpc->bulk_out_len && rpc->bulk_out) - RtlCopyMemory(out_buf + header_len, rpc->bulk_out, *rpc->bulk_out_len); - return header_len + *rpc->bulk_out_len; - } + if (rpc->bulk_out_len && rpc->bulk_out) + RtlCopyMemory(out_buf + header_len, rpc->bulk_out, *rpc->bulk_out_len); + return header_len + *rpc->bulk_out_len; +} #endif #endif @@ -1081,327 +1081,327 @@ rpc_send_reg(rpc_t *rpc, char *out_buf) /* rpc library api */ #ifdef RPC_KERN rpc_recv(char *in_buf, ULONG len) - { - ULONG key, header_size; - char *alloc; - rpc_t *rpc; - - ifs_lock_rpcs(); - - rpc = rpc_find(*(ULONG*)in_buf); - if (!rpc) - { - //_asm int 3; - ifs_unlock_rpcs(); - return -1; - } - - //_asm int 3; - /*if (*rpc->bulk_out_len == 0xFFFFFFFC) - { - ASSERT(rpc->bulk_out); - MmUnmapLockedPages(rpc->bulk_out, rpc->bulk_mdl); - // MmUnlockPages(rpc->bulk_mdl); - }*/ - - alloc = rpc->in_buf; - rpc->in_buf = rpc->in_pos = in_buf; - rpc_unmarshal_long(rpc, &key); - ASSERT(key == rpc->key); - rpc_unmarshal_long(rpc, &rpc->bulk_in_len); - - rpc->in_buf = rpc->in_pos = alloc; - header_size = len - rpc->bulk_in_len; - ASSERT(header_size < 4096); - RtlCopyMemory(rpc->in_buf, in_buf + 2*sizeof(ULONG), header_size - 2*sizeof(ULONG)); - //if (*rpc->bulk_out_len != 0xFFFFFFFC) - { - if (rpc->bulk_in_len && rpc->bulk_in) - { - ASSERT(rpc->bulk_in_len <= rpc->bulk_in_max); - //_asm int 3; - RtlCopyMemory(rpc->bulk_in, in_buf + header_size, rpc->bulk_in_len);//len - header_size - 2*sizeof(ULONG)); - } - } - - KeSetEvent(&rpc->ev, IO_NO_INCREMENT, FALSE); - ifs_unlock_rpcs(); - return 0; - } +{ + ULONG key, header_size; + char *alloc; + rpc_t *rpc; + + ifs_lock_rpcs(); + + rpc = rpc_find(*(ULONG*)in_buf); + if (!rpc) + { + //_asm int 3; + ifs_unlock_rpcs(); + return -1; + } + + //_asm int 3; + /*if (*rpc->bulk_out_len == 0xFFFFFFFC) + { + ASSERT(rpc->bulk_out); + MmUnmapLockedPages(rpc->bulk_out, rpc->bulk_mdl); + // MmUnlockPages(rpc->bulk_mdl); + }*/ + + alloc = rpc->in_buf; + rpc->in_buf = rpc->in_pos = in_buf; + rpc_unmarshal_long(rpc, &key); + ASSERT(key == rpc->key); + rpc_unmarshal_long(rpc, &rpc->bulk_in_len); + + rpc->in_buf = rpc->in_pos = alloc; + header_size = len - rpc->bulk_in_len; + ASSERT(header_size < 4096); + RtlCopyMemory(rpc->in_buf, in_buf + 2*sizeof(ULONG), header_size - 2*sizeof(ULONG)); + //if (*rpc->bulk_out_len != 0xFFFFFFFC) + { + if (rpc->bulk_in_len && rpc->bulk_in) + { + ASSERT(rpc->bulk_in_len <= rpc->bulk_in_max); + //_asm int 3; + RtlCopyMemory(rpc->bulk_in, in_buf + header_size, rpc->bulk_in_len);//len - header_size - 2*sizeof(ULONG)); + } + } + + KeSetEvent(&rpc->ev, IO_NO_INCREMENT, FALSE); + ifs_unlock_rpcs(); + return 0; +} rpc_call(ULONG in_len, char *in_buf, ULONG out_max, char *out_buf, ULONG *out_len) - { - long rpc_code; - ULONG status; - WCHAR name[1024]; - ULONG key, fid; - LARGE_INTEGER user_id; - rpc_t rpc; - - rpc.in_buf = rpc.in_pos = in_buf; - rpc.out_buf = rpc.out_pos = out_buf; - - rpc_unmarshal_long(&rpc, &key); - rpc_unmarshal_long(&rpc, &rpc_code); - - switch (rpc_code) - { - case RPC_BREAK_CALLBACK: - rpc_unmarshal_long(&rpc, &fid); - status = dc_break_callback(fid); - rpc_marshal_long(&rpc, status); - break; - } - *out_len = rpc.out_pos - rpc.out_buf; - return 0; - //ifs_ImpersonateClient(user_id); - } +{ + long rpc_code; + ULONG status; + WCHAR name[1024]; + ULONG key, fid; + LARGE_INTEGER user_id; + rpc_t rpc; + + rpc.in_buf = rpc.in_pos = in_buf; + rpc.out_buf = rpc.out_pos = out_buf; + + rpc_unmarshal_long(&rpc, &key); + rpc_unmarshal_long(&rpc, &rpc_code); + + switch (rpc_code) + { + case RPC_BREAK_CALLBACK: + rpc_unmarshal_long(&rpc, &fid); + status = dc_break_callback(fid); + rpc_marshal_long(&rpc, status); + break; + } + *out_len = rpc.out_pos - rpc.out_buf; + return 0; + //ifs_ImpersonateClient(user_id); +} #endif #ifndef RPC_KERN rpc_parse(rpc_t *rpc) - { - long rpc_code; - ULONG status; - WCHAR name[1024]; - ULONG key; - LARGE_INTEGER user_id; - - rpc_unmarshal_long(rpc, &key); - rpc_unmarshal_long(rpc, &rpc->bulk_in_len); - rpc_unmarshal_longlong(rpc, &user_id); - rpc_unmarshal_long(rpc, &rpc_code); - - ifs_ImpersonateClient(user_id); - - rpc_marshal_long(rpc, key); - rpc->bulk_out_len = (ULONG*)rpc->out_pos; - rpc_marshal_long(rpc, 0); - - switch (rpc_code) - { - case RPC_NAMEI: - { - ULONG fid, length; - char *data; - //rpc_unmarshal_wstr(rpc, name); - rpc_unmarshal_long(rpc, &length); - //data = *((char**)rpc->in_pos); - data = rpc->in_pos; - status = uc_namei((WCHAR*)data, &fid); - //status = uc_namei(name, &fid); - rpc_marshal_long(rpc, status); - rpc_marshal_long(rpc, fid); - } - break; - case RPC_CHECK_ACCESS: - { - ULONG fid, access, granted; - rpc_unmarshal_long(rpc, &fid); - rpc_unmarshal_long(rpc, &access); - status = uc_check_access(fid, access, &granted); - rpc_marshal_long(rpc, status); - rpc_marshal_long(rpc, granted); - } - break; - case RPC_CREATE: - { - LARGE_INTEGER alloc; - ULONG access, granted, fid, attribs; - char *data; - - rpc_unmarshal_long(rpc, &attribs); - rpc_unmarshal_longlong(rpc, &alloc); - rpc_unmarshal_long(rpc, &access); - //rpc_unmarshal_wstr(rpc, name); - data = rpc->in_pos; - status = uc_create((WCHAR*)data, attribs, alloc, access, &granted, &fid); - rpc_marshal_long(rpc, status); - rpc_marshal_long(rpc, granted); - rpc_marshal_long(rpc, fid); - } - break; - case RPC_STAT: - { - ULONG fid, attribs; - LARGE_INTEGER size, creation, access, change, written; - rpc_unmarshal_long(rpc, &fid); - status = uc_stat(fid, &attribs, &size, &creation, &access, &change, &written); - rpc_marshal_long(rpc, status); - rpc_marshal_long(rpc, attribs); - rpc_marshal_longlong(rpc, size); - rpc_marshal_longlong(rpc, creation); - rpc_marshal_longlong(rpc, access); - rpc_marshal_longlong(rpc, change); - rpc_marshal_longlong(rpc, written); - } - break; - case RPC_READ: - { - ULONG fid, length, read; - LARGE_INTEGER offset; - char *data, *save; - rpc_unmarshal_long(rpc, &fid); - rpc_unmarshal_longlong(rpc, &offset); - rpc_unmarshal_long(rpc, &length); - save = rpc->out_pos; - rpc_marshal_long(rpc, 0); - rpc_marshal_long(rpc, 0); - data = rpc->out_pos; - rpc->out_pos = save; - status = uc_read(fid, offset, length, &read, data); - rpc_marshal_long(rpc, status); - rpc_marshal_long(rpc, read); - rpc->out_pos += read; - *rpc->bulk_out_len = read; - } - break; +{ + long rpc_code; + ULONG status; + WCHAR name[1024]; + ULONG key; + LARGE_INTEGER user_id; + + rpc_unmarshal_long(rpc, &key); + rpc_unmarshal_long(rpc, &rpc->bulk_in_len); + rpc_unmarshal_longlong(rpc, &user_id); + rpc_unmarshal_long(rpc, &rpc_code); + + ifs_ImpersonateClient(user_id); + + rpc_marshal_long(rpc, key); + rpc->bulk_out_len = (ULONG*)rpc->out_pos; + rpc_marshal_long(rpc, 0); + + switch (rpc_code) + { + case RPC_NAMEI: + { + ULONG fid, length; + char *data; + //rpc_unmarshal_wstr(rpc, name); + rpc_unmarshal_long(rpc, &length); + //data = *((char**)rpc->in_pos); + data = rpc->in_pos; + status = uc_namei((WCHAR*)data, &fid); + //status = uc_namei(name, &fid); + rpc_marshal_long(rpc, status); + rpc_marshal_long(rpc, fid); + } + break; + case RPC_CHECK_ACCESS: + { + ULONG fid, access, granted; + rpc_unmarshal_long(rpc, &fid); + rpc_unmarshal_long(rpc, &access); + status = uc_check_access(fid, access, &granted); + rpc_marshal_long(rpc, status); + rpc_marshal_long(rpc, granted); + } + break; + case RPC_CREATE: + { + LARGE_INTEGER alloc; + ULONG access, granted, fid, attribs; + char *data; + + rpc_unmarshal_long(rpc, &attribs); + rpc_unmarshal_longlong(rpc, &alloc); + rpc_unmarshal_long(rpc, &access); + //rpc_unmarshal_wstr(rpc, name); + data = rpc->in_pos; + status = uc_create((WCHAR*)data, attribs, alloc, access, &granted, &fid); + rpc_marshal_long(rpc, status); + rpc_marshal_long(rpc, granted); + rpc_marshal_long(rpc, fid); + } + break; + case RPC_STAT: + { + ULONG fid, attribs; + LARGE_INTEGER size, creation, access, change, written; + rpc_unmarshal_long(rpc, &fid); + status = uc_stat(fid, &attribs, &size, &creation, &access, &change, &written); + rpc_marshal_long(rpc, status); + rpc_marshal_long(rpc, attribs); + rpc_marshal_longlong(rpc, size); + rpc_marshal_longlong(rpc, creation); + rpc_marshal_longlong(rpc, access); + rpc_marshal_longlong(rpc, change); + rpc_marshal_longlong(rpc, written); + } + break; + case RPC_READ: + { + ULONG fid, length, read; + LARGE_INTEGER offset; + char *data, *save; + rpc_unmarshal_long(rpc, &fid); + rpc_unmarshal_longlong(rpc, &offset); + rpc_unmarshal_long(rpc, &length); + save = rpc->out_pos; + rpc_marshal_long(rpc, 0); + rpc_marshal_long(rpc, 0); + data = rpc->out_pos; + rpc->out_pos = save; + status = uc_read(fid, offset, length, &read, data); + rpc_marshal_long(rpc, status); + rpc_marshal_long(rpc, read); + rpc->out_pos += read; + *rpc->bulk_out_len = read; + } + break; /* case RPC_READ_BULK: - { - ULONG fid, length, read; - LARGE_INTEGER offset; - char *data, *save; - rpc_unmarshal_long(rpc, &fid); - rpc_unmarshal_longlong(rpc, &offset); - rpc_unmarshal_long(rpc, &length); - data = *((char**)rpc->in_pos); - status = uc_read(fid, offset, length, &read, data); - rpc_marshal_long(rpc, status); - rpc_marshal_long(rpc, read); - *rpc->bulk_out_len = 0; - } - break;*/ - case RPC_WRITE: - { - ULONG fid, length, written; - LARGE_INTEGER offset; - char *data; - rpc_unmarshal_long(rpc, &fid); - rpc_unmarshal_longlong(rpc, &offset); - rpc_unmarshal_long(rpc, &length); - data = rpc->in_pos; - status = uc_write(fid, offset, length, &written, data); - rpc_marshal_long(rpc, status); - rpc_marshal_long(rpc, written); - } - break; + { + ULONG fid, length, read; + LARGE_INTEGER offset; + char *data, *save; + rpc_unmarshal_long(rpc, &fid); + rpc_unmarshal_longlong(rpc, &offset); + rpc_unmarshal_long(rpc, &length); + data = *((char**)rpc->in_pos); + status = uc_read(fid, offset, length, &read, data); + rpc_marshal_long(rpc, status); + rpc_marshal_long(rpc, read); + *rpc->bulk_out_len = 0; + } + break;*/ + case RPC_WRITE: + { + ULONG fid, length, written; + LARGE_INTEGER offset; + char *data; + rpc_unmarshal_long(rpc, &fid); + rpc_unmarshal_longlong(rpc, &offset); + rpc_unmarshal_long(rpc, &length); + data = rpc->in_pos; + status = uc_write(fid, offset, length, &written, data); + rpc_marshal_long(rpc, status); + rpc_marshal_long(rpc, written); + } + break; /* case RPC_WRITE_BULK: - { - ULONG fid, length, written; - LARGE_INTEGER offset; - char *data; - //_asm int 3; - rpc_unmarshal_long(rpc, &fid); - rpc_unmarshal_longlong(rpc, &offset); - rpc_unmarshal_long(rpc, &length); - data = *((char**)rpc->in_pos); - status = uc_write(fid, offset, length, &written, data); - rpc_marshal_long(rpc, status); - rpc_marshal_long(rpc, written); - } - break;*/ - case RPC_TRUNC: - { - ULONG fid; - LARGE_INTEGER size; - rpc_unmarshal_long(rpc, &fid); - rpc_unmarshal_longlong(rpc, &size); - status = uc_trunc(fid, size); - rpc_marshal_long(rpc, status); - } - break; - case RPC_SETINFO: - { - ULONG fid, attribs; - LARGE_INTEGER creation, access, change, written; - rpc_unmarshal_long(rpc, &fid); - rpc_unmarshal_long(rpc, &attribs); - rpc_unmarshal_longlong(rpc, &creation); - rpc_unmarshal_longlong(rpc, &access); - rpc_unmarshal_longlong(rpc, &change); - rpc_unmarshal_longlong(rpc, &written); - status = uc_setinfo(fid, attribs, creation, access, change, written); - rpc_marshal_long(rpc, status); - } - break; - case RPC_READDIR: - { - ULONG fid, count, len; - LARGE_INTEGER cookie_in; - char *data, *save; - rpc_unmarshal_long(rpc, &fid); - rpc_unmarshal_longlong(rpc, &cookie_in); - rpc_unmarshal_wstr(rpc, name); - rpc_unmarshal_long(rpc, &len); - save = rpc->out_pos; - rpc_marshal_long(rpc, 0); - rpc_marshal_long(rpc, 0); - rpc_marshal_long(rpc, 0); - data = rpc->out_pos; - rpc->out_pos = save; - status = uc_readdir(fid, cookie_in, name, &count, data, &len); - rpc_marshal_long(rpc, status); - rpc_marshal_long(rpc, count); - rpc_marshal_long(rpc, len); - rpc->out_pos += len; - *rpc->bulk_out_len = len; - } - break; - case RPC_CLOSE: - { - ULONG fid; - rpc_unmarshal_long(rpc, &fid); - status = uc_close(fid); - rpc_marshal_long(rpc, status); - } - break; - case RPC_UNLINK: - { - ULONG fid, unlink; - rpc_unmarshal_wstr(rpc, name); - status = uc_unlink(name); - rpc_marshal_long(rpc, status); - } - break; - case RPC_IOCTL_WRITE: - { - ULONG length, key; - rpc_unmarshal_long(rpc, &length); - status = uc_ioctl_write(length, rpc->in_pos, &key); - rpc_marshal_long(rpc, status); - rpc_marshal_long(rpc, key); - } - break; - case RPC_IOCTL_READ: - { - ULONG key, length; - char *save, *data; - rpc_unmarshal_long(rpc, &key); - save = rpc->out_pos; - rpc_marshal_long(rpc, 0); - rpc_marshal_long(rpc, 0); - data = rpc->out_pos; - rpc->out_pos = save; - status = uc_ioctl_read(key, &length, data); - rpc_marshal_long(rpc, status); - rpc_marshal_long(rpc, length); - rpc->out_pos += length; - *rpc->bulk_out_len = length; - } - break; - case RPC_RENAME: - { - ULONG fid, new_fid; - WCHAR curr[1024], new_dir[1024], new_name[1024]; - rpc_unmarshal_long(rpc, &fid); - rpc_unmarshal_wstr(rpc, curr); - rpc_unmarshal_wstr(rpc, new_dir); - rpc_unmarshal_wstr(rpc, new_name); - status = uc_rename(fid, curr, new_dir, new_name, &new_fid); - rpc_marshal_long(rpc, status); - rpc_marshal_long(rpc, new_fid); - } - break; - } - } + { + ULONG fid, length, written; + LARGE_INTEGER offset; + char *data; + //_asm int 3; + rpc_unmarshal_long(rpc, &fid); + rpc_unmarshal_longlong(rpc, &offset); + rpc_unmarshal_long(rpc, &length); + data = *((char**)rpc->in_pos); + status = uc_write(fid, offset, length, &written, data); + rpc_marshal_long(rpc, status); + rpc_marshal_long(rpc, written); + } + break;*/ + case RPC_TRUNC: + { + ULONG fid; + LARGE_INTEGER size; + rpc_unmarshal_long(rpc, &fid); + rpc_unmarshal_longlong(rpc, &size); + status = uc_trunc(fid, size); + rpc_marshal_long(rpc, status); + } + break; + case RPC_SETINFO: + { + ULONG fid, attribs; + LARGE_INTEGER creation, access, change, written; + rpc_unmarshal_long(rpc, &fid); + rpc_unmarshal_long(rpc, &attribs); + rpc_unmarshal_longlong(rpc, &creation); + rpc_unmarshal_longlong(rpc, &access); + rpc_unmarshal_longlong(rpc, &change); + rpc_unmarshal_longlong(rpc, &written); + status = uc_setinfo(fid, attribs, creation, access, change, written); + rpc_marshal_long(rpc, status); + } + break; + case RPC_READDIR: + { + ULONG fid, count, len; + LARGE_INTEGER cookie_in; + char *data, *save; + rpc_unmarshal_long(rpc, &fid); + rpc_unmarshal_longlong(rpc, &cookie_in); + rpc_unmarshal_wstr(rpc, name); + rpc_unmarshal_long(rpc, &len); + save = rpc->out_pos; + rpc_marshal_long(rpc, 0); + rpc_marshal_long(rpc, 0); + rpc_marshal_long(rpc, 0); + data = rpc->out_pos; + rpc->out_pos = save; + status = uc_readdir(fid, cookie_in, name, &count, data, &len); + rpc_marshal_long(rpc, status); + rpc_marshal_long(rpc, count); + rpc_marshal_long(rpc, len); + rpc->out_pos += len; + *rpc->bulk_out_len = len; + } + break; + case RPC_CLOSE: + { + ULONG fid; + rpc_unmarshal_long(rpc, &fid); + status = uc_close(fid); + rpc_marshal_long(rpc, status); + } + break; + case RPC_UNLINK: + { + ULONG fid, unlink; + rpc_unmarshal_wstr(rpc, name); + status = uc_unlink(name); + rpc_marshal_long(rpc, status); + } + break; + case RPC_IOCTL_WRITE: + { + ULONG length, key; + rpc_unmarshal_long(rpc, &length); + status = uc_ioctl_write(length, rpc->in_pos, &key); + rpc_marshal_long(rpc, status); + rpc_marshal_long(rpc, key); + } + break; + case RPC_IOCTL_READ: + { + ULONG key, length; + char *save, *data; + rpc_unmarshal_long(rpc, &key); + save = rpc->out_pos; + rpc_marshal_long(rpc, 0); + rpc_marshal_long(rpc, 0); + data = rpc->out_pos; + rpc->out_pos = save; + status = uc_ioctl_read(key, &length, data); + rpc_marshal_long(rpc, status); + rpc_marshal_long(rpc, length); + rpc->out_pos += length; + *rpc->bulk_out_len = length; + } + break; + case RPC_RENAME: + { + ULONG fid, new_fid; + WCHAR curr[1024], new_dir[1024], new_name[1024]; + rpc_unmarshal_long(rpc, &fid); + rpc_unmarshal_wstr(rpc, curr); + rpc_unmarshal_wstr(rpc, new_dir); + rpc_unmarshal_wstr(rpc, new_name); + status = uc_rename(fid, curr, new_dir, new_name, &new_fid); + rpc_marshal_long(rpc, status); + rpc_marshal_long(rpc, new_fid); + } + break; + } +} #endif diff --git a/src/WINNT/afsrdr/ifs_rpc.h b/src/WINNT/afsrdr/ifs_rpc.h index b5784f73e..9fa1abb0c 100644 --- a/src/WINNT/afsrdr/ifs_rpc.h +++ b/src/WINNT/afsrdr/ifs_rpc.h @@ -38,29 +38,29 @@ #endif /* upcalls */ -#define RPC_NAMEI 0x10 +#define RPC_NAMEI 0x10 #define RPC_CHECK_ACCESS 0x11 -#define RPC_CREATE 0x12 -#define RPC_STAT 0x13 -#define RPC_READ 0x14 -#define RPC_WRITE 0x15 -#define RPC_TRUNC 0x16 -#define RPC_SETINFO 0x17 -#define RPC_READDIR 0x18 -#define RPC_CLOSE 0x19 -#define RPC_UNLINK 0x1A +#define RPC_CREATE 0x12 +#define RPC_STAT 0x13 +#define RPC_READ 0x14 +#define RPC_WRITE 0x15 +#define RPC_TRUNC 0x16 +#define RPC_SETINFO 0x17 +#define RPC_READDIR 0x18 +#define RPC_CLOSE 0x19 +#define RPC_UNLINK 0x1A #define RPC_IOCTL_WRITE 0x1B #define RPC_IOCTL_READ 0x1C -#define RPC_RENAME 0x1D +#define RPC_RENAME 0x1D #define RPC_READ_BULK 0x1E #define RPC_WRITE_BULK 0x1F /* downcalls */ #define RPC_BREAK_CALLBACK 0x80 -#define TRANSFER_CHUNK_SIZE (1024*1024) -#define RPC_TIMEOUT_SHORT 0 -#define RPC_TIMEOUT_LONG 1 +#define TRANSFER_CHUNK_SIZE (1024*1024) +#define RPC_TIMEOUT_SHORT 0 +#define RPC_TIMEOUT_LONG 1 /* internal data struct for both client and server */ struct rpc diff --git a/src/WINNT/afsrdr/kif.h b/src/WINNT/afsrdr/kif.h index d1237f3ce..513f61d50 100644 --- a/src/WINNT/afsrdr/kif.h +++ b/src/WINNT/afsrdr/kif.h @@ -57,11 +57,11 @@ #define IFSL_NOT_EMPTY (IFSL_FAIL_BASE + 22) #define IFSL_RPC_TIMEOUT (IFSL_FAIL_BASE + 23) #define IFSL_OVERQUOTA (IFSL_FAIL_BASE + 24) -#define IFSL_UNSPEC (IFSL_FAIL_BASE + 25) +#define IFSL_UNSPEC (IFSL_FAIL_BASE + 25) /* ioctl codes */ -#define IOCTL_AFSRDR_IOCTL CTL_CODE(IOCTL_DISK_BASE, 0x007, METHOD_OUT_DIRECT, FILE_ANY_ACCESS) +#define IOCTL_AFSRDR_IOCTL CTL_CODE(IOCTL_DISK_BASE, 0x007, METHOD_OUT_DIRECT, FILE_ANY_ACCESS) #define IOCTL_AFSRDR_DOWNCALL CTL_CODE(IOCTL_DISK_BASE, 0x008, METHOD_OUT_DIRECT, FILE_ANY_ACCESS) #define IOCTL_AFSRDR_GET_PATH CTL_CODE(IOCTL_DISK_BASE, 0x009, METHOD_OUT_DIRECT, FILE_ANY_ACCESS) diff --git a/src/WINNT/client_config/drivemap.cpp b/src/WINNT/client_config/drivemap.cpp index 88856ae85..2a8e30c01 100644 --- a/src/WINNT/client_config/drivemap.cpp +++ b/src/WINNT/client_config/drivemap.cpp @@ -6,7 +6,7 @@ * License. For details, see the LICENSE file in the top-level source * directory or online at http://www.openafs.org/dl/license10.html */ -/* copyright (c) 2005 +/* AFSIFS portions copyright (c) 2005 * the regents of the university of michigan * all rights reserved * @@ -339,24 +339,26 @@ BOOL SubmountToPath (PDRIVEMAPLIST pList, LPTSTR pszPath, LPTSTR pszSubmount, BO // Otherwise, look up our list of submounts. // #ifdef AFSIFS - AdjustAfsPath (pszPath, pszSubmount, TRUE, TRUE); + AdjustAfsPath (pszPath, pszSubmount, TRUE, TRUE); #endif - for (size_t ii = 0; ii < pList->cSubmounts; ++ii) - { + for (size_t ii = 0; ii < pList->cSubmounts; ++ii) + { + BOOL b; #ifndef AFSIFS - if (!lstrcmpi (pList->aSubmounts[ii].szSubmount, pszSubmount)) + b = !lstrcmpi (pList->aSubmounts[ii].szSubmount, pszSubmount); #else - if (!lstrcmpi (pList->aSubmounts[ii].szMapping, pszPath)) + b = !lstrcmpi (pList->aSubmounts[ii].szMapping, pszPath); #endif - { - if (fMarkInUse) - pList->aSubmounts[ii].fInUse = TRUE; - AdjustAfsPath (pszPath, pList->aSubmounts[ii].szMapping, TRUE, TRUE); - return TRUE; - } - } + if (b) + { + if (fMarkInUse) + pList->aSubmounts[ii].fInUse = TRUE; + AdjustAfsPath (pszPath, pList->aSubmounts[ii].szMapping, TRUE, TRUE); + return TRUE; + } + } - return FALSE; + return FALSE; } @@ -846,17 +848,18 @@ BOOL ActivateDriveMap (TCHAR chDrive, LPTSTR pszMapping, LPTSTR pszSubmountReq, } // We now have a submount name and drive letter--map the network drive. + DWORD rc; #ifndef AFSIFS - DWORD rc=MountDOSDrive(chDrive,szSubmount,fPersistent,NULL); + rc=MountDOSDrive(chDrive,szSubmount,fPersistent,NULL); #else - DWORD rc=MountDOSDrive(chDrive,/*szSubmount*/pszMapping,fPersistent,NULL); + rc=MountDOSDrive(chDrive,/*szSubmount*/pszMapping,fPersistent,NULL); #endif - if (rc == NO_ERROR) - return TRUE; + if (rc == NO_ERROR) + return TRUE; - if (pdwStatus) - *pdwStatus = rc; - return FALSE; + if (pdwStatus) + *pdwStatus = rc; + return FALSE; } @@ -966,12 +969,14 @@ BOOL GetDriveSubmount (TCHAR chDrive, LPTSTR pszSubmountNow) // : Authentication ID, 16 char hex. // : Netbios name of server // + BOOL b; #ifndef AFSIFS - if (_tcsnicmp(szMapping, cszLANMANDEVICE, _tcslen(cszLANMANDEVICE))) + b = _tcsnicmp(szMapping, cszLANMANDEVICE, _tcslen(cszLANMANDEVICE)); #else - const TCHAR ker_sub_path[] = "\\Device\\afsrdr\\"; - if (_tcsnicmp(szMapping, ker_sub_path, _tcslen(ker_sub_path))) + const TCHAR ker_sub_path[] = "\\Device\\afsrdr\\"; + b = _tcsnicmp(szMapping, ker_sub_path, _tcslen(ker_sub_path)); #endif + if (b) return FALSE; #ifndef AFSIFS pszSubmount = &szMapping[ _tcslen(cszLANMANDEVICE) ]; @@ -980,17 +985,17 @@ BOOL GetDriveSubmount (TCHAR chDrive, LPTSTR pszSubmountNow) #endif #ifdef AFSIFS - if (*(pszSubmount) < '0' || - *(pszSubmount) > '9') - return FALSE; - ++pszSubmount; -#else + if (*(pszSubmount) < '0' || + *(pszSubmount) > '9') + return FALSE; + ++pszSubmount; +#else if (IsWindows2000()) - { + { if (*(pszSubmount) != TEXT(';')) return FALSE; - } else - --pszSubmount; + } else + --pszSubmount; if (toupper(*(++pszSubmount)) != chDrive) return FALSE; @@ -1421,36 +1426,34 @@ DWORD MountDOSDrive(char chDrive,const char *szSubmount,BOOL bPersistent,const c TCHAR szDrive[3] = TEXT("?:"); #ifdef AFSIFS - int pathCount, currPos, lastPos, x; + int pathCount, currPos, lastPos, x; - pathCount = 0; - - pathCount = 0; - strcpy(szTokens, szSubmount); - tok = strtok(szTokens, "/\\"); - strcpy(szPath, ""); - while (tok) - { - if (pathCount || stricmp(tok, "afs")) - { - strcat(szPath, "\\"); - strcat(szPath, tok); - pathCount++; - } - tok = strtok(NULL, "/\\"); - } + pathCount = 0; - sprintf(szDrive,"%c:",chDrive); - strcpy(szTokens, szPath); - sprintf(szPath,"\\Device\\afsrdr\\%d%s",pathCount,szTokens); - //succ = DefineDosDevice(DDD_RAW_TARGET_PATH, "J:", "\\Device\\afsrdr\\2\\ericjw\\test"); - succ = DefineDosDevice(DDD_RAW_TARGET_PATH, szDrive, szPath); - err = GetLastError(); + pathCount = 0; + strcpy(szTokens, szSubmount); + tok = strtok(szTokens, "/\\"); + strcpy(szPath, ""); + while (tok) + { + if (pathCount || stricmp(tok, "afs")) + { + strcat(szPath, "\\"); + strcat(szPath, tok); + pathCount++; + } + tok = strtok(NULL, "/\\"); + } - return succ ? NO_ERROR : ERROR_DEVICE_IN_USE; + sprintf(szDrive,"%c:",chDrive); + strcpy(szTokens, szPath); + sprintf(szPath,"\\Device\\afsrdr\\%d%s",pathCount,szTokens); + //succ = DefineDosDevice(DDD_RAW_TARGET_PATH, "J:", "\\Device\\afsrdr\\2\\ericjw\\test"); + succ = DefineDosDevice(DDD_RAW_TARGET_PATH, szDrive, szPath); + err = GetLastError(); + return succ ? NO_ERROR : ERROR_DEVICE_IN_USE; #else - sprintf(szDrive,"%c:",chDrive); GetClientNetbiosName (szClient); sprintf(szPath,"\\\\%s\\%s",szClient,szSubmount); @@ -1474,9 +1477,9 @@ DWORD DisMountDOSDriveFull(const char *szPath,BOOL bForce) DWORD res=WNetCancelConnection(szPath,bForce); #else DWORD res; - res = ERROR_DEVICE_IN_USE; - // must handle drive letters and afs paths - //DDD_REMOVE_DEFINITION + res = ERROR_DEVICE_IN_USE; + // must handle drive letters and afs paths + // DDD_REMOVE_DEFINITION #endif DEBUG_EVENT3("AFS DriveMap","%sDismount Remote[%s]=%x", bForce ? "Forced " : "",szPath,res); @@ -1496,12 +1499,12 @@ DWORD DisMountDOSDrive(const char *pSubmount,BOOL bForce) DWORD DisMountDOSDrive(const char chDrive,BOOL bForce) { TCHAR szPath[MAX_PATH]; - DWORD succ; + DWORD succ; - sprintf(szPath,"%c:",chDrive); + sprintf(szPath,"%c:",chDrive); #ifdef AFSIFS - succ = DefineDosDevice(DDD_REMOVE_DEFINITION, szPath, NULL); - return (!succ) ? GetLastError() : 0; + succ = DefineDosDevice(DDD_REMOVE_DEFINITION, szPath, NULL); + return (!succ) ? GetLastError() : 0; #else return DisMountDOSDriveFull(szPath,bForce); #endif diff --git a/src/config/NTMakefile.amd64_w2k b/src/config/NTMakefile.amd64_w2k index 87fea4e14..53512ca50 100644 --- a/src/config/NTMakefile.amd64_w2k +++ b/src/config/NTMakefile.amd64_w2k @@ -80,7 +80,7 @@ LIB = $(AFSDEV_LIB) #define used in WinNT/2000 installation and program version display AFSPRODUCT_VER_MAJOR=1 AFSPRODUCT_VER_MINOR=3 -AFSPRODUCT_VER_PATCH=8400 +AFSPRODUCT_VER_PATCH=8401 AFSPRODUCT_VER_BUILD=0 # For MSI installer, each major release should have a different GUID @@ -251,13 +251,17 @@ afscflags = $(afscflags) /GX !ENDIF !IF ("$(AFSVER_CL)"!="1200") -afscdefs = $(afscdefs) /GT /GS +afscflags = $(afscflags) /GT /GS #/Wp64 !IF ("$(AFSVER_CL)"!="1400") -afscdefs = $(afscdefs) /G7 +afscflags = $(afscflags) /G7 !ENDIF !ENDIF +!IF ("$(AFSIFS)" == "TRUE") +afscdefs = $(afscdefs) -DAFSIFS +!ENDIF + !IF ("$(AFSDEV_BUILDTYPE)" == "FREE") afscflags = $(afscflags) /Ox /Zi diff --git a/src/config/NTMakefile.i386_nt40 b/src/config/NTMakefile.i386_nt40 index 894fcb304..32dab2119 100644 --- a/src/config/NTMakefile.i386_nt40 +++ b/src/config/NTMakefile.i386_nt40 @@ -80,7 +80,7 @@ LIB = $(AFSDEV_LIB) #define used in WinNT/2000 installation and program version display AFSPRODUCT_VER_MAJOR=1 AFSPRODUCT_VER_MINOR=3 -AFSPRODUCT_VER_PATCH=8400 +AFSPRODUCT_VER_PATCH=8401 AFSPRODUCT_VER_BUILD=0 # For MSI installer, each major release should have a different GUID @@ -257,9 +257,7 @@ afscdefs = $(afscdefs) /G7 !ENDIF !IF ("$(AFSIFS)" == "TRUE") -dafsifs = "-DAFSIFS" -!ELSE -dafsifs = "" +afscdefs = $(afscdefs) -DAFSIFS !ENDIF !IF ("$(AFSDEV_BUILDTYPE)" == "FREE") @@ -273,13 +271,15 @@ NODEBUG=1 cdebug = $(cdebug:-Z7=-Zi) # avoid annoying override warning (D4025) !IF ("$(AFSVER_CL)"=="1200") -afscdefs = $(afscdefs) -DDEBUG /GZ +afscdefs = $(afscdefs) -DDEBUG +afscflags = $(afscflags) /GZ !ELSE -afscdefs = $(afscdefs) -DDEBUG /RTCs /RTCu +afscdefs = $(afscdefs) -DDEBUG +afscflags = $(afscflags) /RTCs /RTCu !ENDIF !IFDEF _CRTDBG_MAP_ALLOC -afscflags = $(afscflags) -D_DEBUG -D_CRTDBG_MAP_ALLOC +afscdefs = $(afscdefs) -D_DEBUG -D_CRTDBG_MAP_ALLOC !ENDIF !UNDEF NODEBUG diff --git a/src/config/NTMakefile.i386_w2k b/src/config/NTMakefile.i386_w2k index f0e28b00f..d41b40560 100644 --- a/src/config/NTMakefile.i386_w2k +++ b/src/config/NTMakefile.i386_w2k @@ -80,7 +80,7 @@ LIB = $(AFSDEV_LIB) #define used in WinNT/2000 installation and program version display AFSPRODUCT_VER_MAJOR=1 AFSPRODUCT_VER_MINOR=3 -AFSPRODUCT_VER_PATCH=8400 +AFSPRODUCT_VER_PATCH=8401 AFSPRODUCT_VER_BUILD=0 # For MSI installer, each major release should have a different GUID @@ -249,13 +249,17 @@ afscflags = $(afscflags) /GX !ENDIF !IF ("$(AFSVER_CL)"!="1200") -afscdefs = $(afscdefs) /GT /GS +afscflags = $(afscflags) /GT /GS #/Wp64 !IF ("$(AFSVER_CL)"!="1400") -afscdefs = $(afscdefs) /G7 +afscflags = $(afscflags) /G7 !ENDIF !ENDIF +!IF ("$(AFSIFS)" == "TRUE") +afscdefs = $(afscdefs) -DAFSIFS +!ENDIF + !IF ("$(AFSDEV_BUILDTYPE)" == "FREE") afscflags = $(afscflags) /Ox /Zi diff --git a/src/sys/pioctl_nt.c b/src/sys/pioctl_nt.c index 67da815e8..79d9d90a9 100644 --- a/src/sys/pioctl_nt.c +++ b/src/sys/pioctl_nt.c @@ -6,7 +6,7 @@ * License. For details, see the LICENSE file in the top-level source * directory or online at http://www.openafs.org/dl/license10.html */ -/* copyright (c) 2005 +/* AFSIFS portions copyright (c) 2005 * the regents of the university of michigan * all rights reserved * @@ -391,8 +391,8 @@ GetIoctlHandle(char *fileNamep, HANDLE * handlep) lana_GetNetbiosName(netbiosName,LANA_NETBIOS_NAME_FULL); sprintf(tbuffer,"\\\\%s\\all%s",netbiosName,SMB_IOCTL_FILENAME); } -#else - sprintf(tbuffer,"\\\\.\\afscom\\ioctl"); +#else + sprintf(tbuffer,"\\\\.\\afscom\\ioctl"); #endif fflush(stdout); @@ -404,9 +404,9 @@ GetIoctlHandle(char *fileNamep, HANDLE * handlep) fflush(stdout); #ifdef AFSIFS - if (fh == INVALID_HANDLE_VALUE) { - return -1; - } + if (fh == INVALID_HANDLE_VALUE) { + return -1; + } #endif if (fh == INVALID_HANDLE_VALUE) { @@ -640,7 +640,7 @@ Transceive(HANDLE handle, fs_ioctlRequest_t * reqp) } #ifndef AFSIFS - if (!WriteFile(handle, reqp->data, rcount, &ioCount, NULL)) { + if (!WriteFile(handle, reqp->data, rcount, &ioCount, NULL)) { /* failed to write */ gle = GetLastError(); @@ -658,15 +658,15 @@ Transceive(HANDLE handle, fs_ioctlRequest_t * reqp) return gle; } #else - /* ioctl completes as one operation, so copy input to a new buffer, and use as output buffer */ - data = malloc(rcount); - memcpy(data, reqp->data, rcount); - if (!DeviceIoControl(handle, IOCTL_AFSRDR_IOCTL, data, rcount, reqp->data, sizeof(reqp->data), &ioCount, NULL)) - { - free(data); - return GetLastError(); - } - free(data); + /* ioctl completes as one operation, so copy input to a new buffer, and use as output buffer */ + data = malloc(rcount); + memcpy(data, reqp->data, rcount); + if (!DeviceIoControl(handle, IOCTL_AFSRDR_IOCTL, data, rcount, reqp->data, sizeof(reqp->data), &ioCount, NULL)) + { + free(data); + return GetLastError(); + } + free(data); #endif reqp->nbytes = ioCount; /* set # of bytes available */ @@ -746,30 +746,29 @@ fs_GetFullPath(char *pathp, char *outPathp, long outSize) unsigned long length; #ifdef AFSIFS - if (!pathp) - return CM_ERROR_NOSUCHPATH; + if (!pathp) + return CM_ERROR_NOSUCHPATH; - //sprintf(tpath, "%c:\\", pathp[0]); - rootDir = CreateFile(pathp, 0, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); - if (rootDir == INVALID_HANDLE_VALUE) - return CM_ERROR_NOSUCHPATH; + //sprintf(tpath, "%c:\\", pathp[0]); + rootDir = CreateFile(pathp, 0, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); + if (rootDir == INVALID_HANDLE_VALUE) + return CM_ERROR_NOSUCHPATH; - wpath = tpath; - length = 0; - if (!DeviceIoControl(rootDir, IOCTL_AFSRDR_GET_PATH, NULL, 0, wpath, 1000, &length, NULL)) - { - CloseHandle(rootDir); - return CM_ERROR_NOSUCHPATH; - } - CloseHandle(rootDir); + wpath = tpath; + length = 0; + if (!DeviceIoControl(rootDir, IOCTL_AFSRDR_GET_PATH, NULL, 0, wpath, 1000, &length, NULL)) + { + CloseHandle(rootDir); + return CM_ERROR_NOSUCHPATH; + } + CloseHandle(rootDir); - code = WideCharToMultiByte(CP_UTF8, 0/*WC_NO_BEST_FIT_CHARS*/, wpath, length/sizeof(wchar_t), outPathp, outSize/sizeof(wchar_t), NULL, NULL); + code = WideCharToMultiByte(CP_UTF8, 0/*WC_NO_BEST_FIT_CHARS*/, wpath, length/sizeof(wchar_t), outPathp, outSize/sizeof(wchar_t), NULL, NULL); // strcpy(outPathp, tpath); - return 0; + return 0; #endif - if (pathp[0] != 0 && pathp[1] == ':') { /* there's a drive letter there */ firstp = pathp + 2; -- 2.39.5