fid->hash = FileId->Hash;
}
+unsigned long
+RDR_ExtAttributes(cm_scache_t *scp)
+{
+ unsigned long attrs;
+
+ if (scp->fileType == CM_SCACHETYPE_DIRECTORY ||
+ scp->fid.vnode & 0x1)
+ {
+ attrs = SMB_ATTR_DIRECTORY;
+#ifdef SPECIAL_FOLDERS
+ attrs |= SMB_ATTR_SYSTEM; /* FILE_ATTRIBUTE_SYSTEM */
+#endif /* SPECIAL_FOLDERS */
+ } else if ( scp->fileType == CM_SCACHETYPE_MOUNTPOINT ||
+ scp->fileType == CM_SCACHETYPE_DFSLINK ||
+ scp->fileType == CM_SCACHETYPE_INVALID)
+ {
+ attrs = SMB_ATTR_DIRECTORY | SMB_ATTR_REPARSE_POINT;
+ } else if ( scp->fileType == CM_SCACHETYPE_SYMLINK) {
+ attrs = SMB_ATTR_REPARSE_POINT;
+ } else {
+ attrs = 0;
+ }
+
+ if ((scp->unixModeBits & 0200) == 0)
+ attrs |= SMB_ATTR_READONLY; /* Read-only */
+
+ if (attrs == 0)
+ attrs = SMB_ATTR_NORMAL; /* FILE_ATTRIBUTE_NORMAL */
+
+ return attrs;
+}
+
DWORD
RDR_SetInitParams( OUT AFSRedirectorInitInfo **ppRedirInitInfo, OUT DWORD * pRedirInitInfoLen )
{
break;
case CM_SCACHETYPE_MOUNTPOINT:
case CM_SCACHETYPE_INVALID:
+ case CM_SCACHETYPE_DFSLINK:
pCurrentEntry->FileAttributes = SMB_ATTR_DIRECTORY | SMB_ATTR_REPARSE_POINT;
break;
case CM_SCACHETYPE_SYMLINK:
pCurrentEntry->FileAttributes = SMB_ATTR_NORMAL;
}
} else
- pCurrentEntry->FileAttributes = smb_ExtAttributes(scp);
+ pCurrentEntry->FileAttributes = RDR_ExtAttributes(scp);
pCurrentEntry->EaSize = 0;
pCurrentEntry->Links = scp->linkCount;
wtarget = (WCHAR *)((PBYTE)pCurrentEntry + pCurrentEntry->TargetNameOffset);
if (dwFlags & RDR_POP_EVALUATE_SYMLINKS) {
- char * mp;
code2 = cm_HandleLink(scp, userp, reqp);
if (code2 == 0) {
- mp = scp->mountPointStringp;
- len = strlen(mp);
- if ( len != 0 ) {
- /* Strip off the msdfs: prefix from the target name for the file system */
- if (scp->fileType == CM_SCACHETYPE_DFSLINK) {
- osi_Log0(afsd_logp, "RDR_PopulateCurrentEntry DFSLink Detected");
- pCurrentEntry->FileType = scp->fileType;
-
- if (!strncmp("msdfs:", mp, 6)) {
- mp += 6;
- len -= 6;
- }
+ size_t wtarget_len = 0;
+
+ if (scp->mountPointStringp[0]) {
+ char * mp;
+ char * s;
+ size_t offset = 0;
+
+ len = strlen(scp->mountPointStringp) + 1;
+ mp = strdup(scp->mountPointStringp);
+
+ for (s=mp; *s; s++) {
+ if (*s == '/')
+ *s = '\\';
}
- /* only send one slash to the redirector */
- if (mp[0] == '\\' && mp[1] == '\\') {
- mp++;
- len--;
+
+ if (strncmp("msdfs:", mp, 6) == 0) {
+ offset = 6;
}
+
+
+ if ( mp[offset + 1] == ':' && mp[offset] != '\\') {
+ /* Local drive letter. Must return <drive>:\<path> */
+ pCurrentEntry->FileType = CM_SCACHETYPE_DFSLINK;
+ wtarget_len = len - offset;
#ifdef UNICODE
- cch = MultiByteToWideChar( CP_UTF8, 0, mp,
- len * sizeof(char),
- wtarget,
- len * sizeof(WCHAR));
+ cch = MultiByteToWideChar( CP_UTF8, 0, &mp[offset],
+ wtarget_len * sizeof(char),
+ wtarget,
+ wtarget_len * sizeof(WCHAR));
#else
- mbstowcs(wtarget, mp, len);
+ mbstowcs(wtarget, &mp[offset], wtarget_len);
#endif
+ } else if (mp[offset] == '\\') {
+ size_t nbNameLen = strlen(cm_NetbiosName);
+
+ if ( strnicmp(&mp[offset + 1], cm_NetbiosName, nbNameLen) == 0 &&
+ mp[offset + nbNameLen + 1] == '\\')
+ {
+ /* an AFS symlink */
+ pCurrentEntry->FileType = CM_SCACHETYPE_SYMLINK;
+ wtarget_len = len - offset;
+#ifdef UNICODE
+ cch = MultiByteToWideChar( CP_UTF8, 0, &mp[offset],
+ wtarget_len * sizeof(char),
+ wtarget,
+ wtarget_len * sizeof(WCHAR));
+#else
+ mbstowcs(wtarget, &mp[offset], wtarget_len);
+#endif
+ } else if ( mp[offset + 1] == '\\' &&
+ strnicmp(&mp[offset + 2], cm_NetbiosName, strlen(cm_NetbiosName)) == 0 &&
+ mp[offset + nbNameLen + 2] == '\\')
+ {
+ /* an AFS symlink */
+ pCurrentEntry->FileType = CM_SCACHETYPE_SYMLINK;
+ wtarget_len = len - offset - 1;
+#ifdef UNICODE
+ cch = MultiByteToWideChar( CP_UTF8, 0, &mp[offset + 1],
+ wtarget_len * sizeof(char),
+ wtarget,
+ wtarget_len * sizeof(WCHAR));
+#else
+ mbstowcs(wtarget, &mp[offset + 1], wtarget_len);
+#endif
+ } else {
+ /*
+ * treat as a UNC path. Needs to be \<server>\<share\<path>
+ */
+ pCurrentEntry->FileType = CM_SCACHETYPE_DFSLINK;
+
+ if ( mp[offset] == '\\' && mp[offset + 1] == '\\')
+ offset++;
+
+ wtarget_len = len - offset;
+#ifdef UNICODE
+ cch = MultiByteToWideChar( CP_UTF8, 0, &mp[offset],
+ wtarget_len * sizeof(char),
+ wtarget,
+ wtarget_len * sizeof(WCHAR));
+#else
+ mbstowcs(wtarget, &mp[offset], wtarget_len);
+#endif
+ }
+ } else {
+ /* Relative AFS Symlink */
+ pCurrentEntry->FileType = CM_SCACHETYPE_SYMLINK;
+ wtarget_len = len - offset;
+#ifdef UNICODE
+ cch = MultiByteToWideChar( CP_UTF8, 0, &mp[offset],
+ wtarget_len * sizeof(char),
+ wtarget,
+ wtarget_len * sizeof(WCHAR));
+#else
+ mbstowcs(wtarget, &mp[offset], wtarget_len);
+#endif
+ }
+
+ free(mp);
}
- pCurrentEntry->TargetNameLength = (ULONG)(sizeof(WCHAR) * len);
+
+ pCurrentEntry->TargetNameLength = (ULONG)(sizeof(WCHAR) * (wtarget_len - 1));
} else {
osi_Log2(afsd_logp, "RDR_PopulateCurrentEntry cm_HandleLink failed scp=0x%p code=0x%x",
scp, code2);
pCurrentEntry->FileId.Unique = fidp->unique;
pCurrentEntry->FileId.Hash = fidp->hash;
- pCurrentEntry->FileType = CM_SCACHETYPE_UNKNOWN;
-
pCurrentEntry->DataVersion.QuadPart = CM_SCACHE_VERSION_BAD;
cm_LargeSearchTimeFromUnixTime(&ft, 0);
pCurrentEntry->EndOfFile.QuadPart = 0;
pCurrentEntry->AllocationSize.QuadPart = 0;
- pCurrentEntry->FileAttributes = 0;
+ if (fidp->vnode & 0x1) {
+ pCurrentEntry->FileType = CM_SCACHETYPE_DIRECTORY;
+ pCurrentEntry->FileAttributes = SMB_ATTR_DIRECTORY;
+ } else {
+ pCurrentEntry->FileType = CM_SCACHETYPE_UNKNOWN;
+ pCurrentEntry->FileAttributes = SMB_ATTR_NORMAL;
pCurrentEntry->EaSize = 0;
+ }
pCurrentEntry->Links = 0;
len = wcslen(shortName);
cm_req_t req;
DWORD status;
FILETIME ft = {0x832cf000, 0x01abfcc4}; /* October 1, 1982 00:00:00 +0600 */
+ afs_uint32 flags;
char volName[32]="(unknown)";
char offLineMsg[256]="server temporarily inaccessible";
memcpy(&pResultCB->VolumeCreationTime, &ft, sizeof(ft));
pResultCB->AvailableAllocationUnits.QuadPart = 0;
- pResultCB->FileSystemAttributes |= FILE_READ_ONLY_VOLUME;
+ if (cm_volumeInfoReadOnlyFlag)
+ pResultCB->FileSystemAttributes |= FILE_READ_ONLY_VOLUME;
pResultCB->VolumeLabelLength = cm_Utf8ToUtf16( "Freelance.Local.Root", -1, pResultCB->VolumeLabel,
(sizeof(pResultCB->VolumeLabel) / sizeof(WCHAR)) + 1);
if ( pResultCB->CellLength )
pResultCB->CellLength--;
} else {
- memcpy(&pResultCB->VolumeCreationTime, &ft, sizeof(ft));
-
volp = cm_GetVolumeByFID(&scp->fid);
if (!volp) {
code = CM_ERROR_NOSUCHVOLUME;
}
volType = cm_VolumeType(volp, scp->fid.volume);
- if (volType == ROVOL || volType == BACKVOL)
+ if (cm_volumeInfoReadOnlyFlag && (volType == ROVOL || volType == BACKVOL))
pResultCB->FileSystemAttributes |= FILE_READ_ONLY_VOLUME;
- code = cm_SyncOp(scp, NULL, userp, &req, PRSFS_READ,
- CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
+ flags = CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS;
+ if (scp->volumeCreationDate == 0)
+ flags |= CM_SCACHESYNC_FORCECB;
+ code = cm_SyncOp(scp, NULL, userp, &req, PRSFS_READ, flags);
if (code == 0)
{
sync_done = 1;
code = cm_MapRPCError(code, &req);
}
+ if ( scp->volumeCreationDate )
+ cm_LargeSearchTimeFromUnixTime(&ft, scp->volumeCreationDate);
+ memcpy(&pResultCB->VolumeCreationTime, &ft, sizeof(ft));
+
if (code == 0) {
if (volType == ROVOL || volType == BACKVOL) {
pResultCB->TotalAllocationUnits.QuadPart = volStat.BlocksInUse;