/****************************/
/* 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;
/****************************/
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;
}
/****************************/
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;
}
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
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;
}
/****************************/
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.
* 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
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;
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;
}