From 3b41209be7a1470e186a87764621c9980ae7448a Mon Sep 17 00:00:00 2001 From: Asanka Herath Date: Thu, 26 Jun 2008 06:43:49 +0000 Subject: [PATCH] windows-unicode-20080626 LICENSE MIT This patch is the second stage of the Unicode conversion. In this stage the cache manager has been converted from using 8-bit UTF8 C strings to 16-bit UTF16 C strings in the SMB, the DNLC, the B+ tree, and other directly related modules. The cm_cell, cm_volume, cm_scache, cm_buf, cm_dcache, and cm_dir modules are left 8-bit because their data is all 8-bit UTF8 since they work only on file server strings. The SMB layer accepts 16-bit UTF16, the B+ tree and DNLC use normalized strings as the key, and everything uses UTF8. Efforts have been made to minimize the number of transitions from UTF8 to UTF16 and back. For the most part strings are tagged with clientchar_t and normchar_t and fschar_t types in order to distinguish between the various types of strings that are in use. other changes include addition prototyping. --- src/WINNT/afsd/afsd.h | 9 +- src/WINNT/afsd/afsd_flushvol.c | 22 +- src/WINNT/afsd/afsd_init.c | 143 +++--- src/WINNT/afsd/afsd_init.h | 2 +- src/WINNT/afsd/afsd_service.c | 5 + src/WINNT/afsd/cm_btree.c | 400 ++++++++------- src/WINNT/afsd/cm_btree.h | 34 +- src/WINNT/afsd/cm_buf.h | 2 + src/WINNT/afsd/cm_callback.c | 16 +- src/WINNT/afsd/cm_conn.h | 20 +- src/WINNT/afsd/cm_dnlc.c | 60 +-- src/WINNT/afsd/cm_dnlc.h | 14 +- src/WINNT/afsd/cm_dns.c | 287 +++++++---- src/WINNT/afsd/cm_dns.h | 6 + src/WINNT/afsd/cm_ioctl.c | 488 +++++++++++-------- src/WINNT/afsd/cm_ioctl.h | 23 +- src/WINNT/afsd/cm_nls.c | 556 ++++++++++++++++++++- src/WINNT/afsd/cm_nls.h | 229 ++++++++- src/WINNT/afsd/cm_scache.h | 2 + src/WINNT/afsd/cm_user.h | 2 +- src/WINNT/afsd/cm_utils.c | 369 ++++++++++++++ src/WINNT/afsd/cm_utils.h | 25 +- src/WINNT/afsd/cm_vnodeops.c | 793 +++++++++++++++--------------- src/WINNT/afsd/cm_vnodeops.h | 151 +++--- src/WINNT/afsd/cm_volstat.c | 50 +- src/WINNT/afsd/cm_volstat.h | 20 +- src/WINNT/afsd/smb.c | 1040 ++++++++++++++++++++------------------- src/WINNT/afsd/smb.h | 94 ++-- src/WINNT/afsd/smb3.c | 1041 +++++++++++++++++----------------------- src/WINNT/afsd/smb3.h | 5 +- src/WINNT/afsd/smb_ioctl.c | 361 +++++++------- src/WINNT/afsd/smb_ioctl.h | 41 +- 32 files changed, 3845 insertions(+), 2465 deletions(-) diff --git a/src/WINNT/afsd/afsd.h b/src/WINNT/afsd/afsd.h index 0067a7c..aa027af 100644 --- a/src/WINNT/afsd/afsd.h +++ b/src/WINNT/afsd/afsd.h @@ -23,6 +23,7 @@ BOOL APIENTRY About(HWND, unsigned int, unsigned int, long); #include #include "cm.h" +#include "cm_nls.h" #include #include @@ -44,9 +45,9 @@ BOOL APIENTRY About(HWND, unsigned int, unsigned int, long); #include "cm_volume.h" #include "cm_dcache.h" #include "cm_access.h" +#include "cm_dir.h" #include "cm_utils.h" #include "cm_vnodeops.h" -#include "cm_dir.h" #include "cm_btree.h" #include "cm_daemon.h" #include "cm_ioctl.h" @@ -55,7 +56,6 @@ BOOL APIENTRY About(HWND, unsigned int, unsigned int, long); #include "cm_memmap.h" #include "cm_freelance.h" #include "cm_performance.h" -#include "cm_nls.h" #include "smb_ioctl.h" #include "afsd_init.h" #include "afsd_eventlog.h" @@ -83,9 +83,12 @@ extern cm_scache_t *cm_rootSCachep; extern osi_log_t *afsd_logp; -extern char cm_mountRoot[]; +extern fschar_t cm_mountRoot[]; extern DWORD cm_mountRootLen; +extern clientchar_t cm_mountRootC[]; +extern DWORD cm_mountRootCLen; + extern char cm_CachePath[]; extern BOOL isGateway; diff --git a/src/WINNT/afsd/afsd_flushvol.c b/src/WINNT/afsd/afsd_flushvol.c index 640e9ec..124c1b6 100644 --- a/src/WINNT/afsd/afsd_flushvol.c +++ b/src/WINNT/afsd/afsd_flushvol.c @@ -64,18 +64,18 @@ afsd_ServicePerformFlushVolumes() CONST CHAR COLON = ':'; CONST CHAR SLASH = '\\'; CONST DWORD NETRESBUFSIZE = 16384; - CHAR bufMessage[1024]; - UINT i; - DWORD dwServerSize; - DWORD dwRet; - DWORD dwCount; - DWORD dwNetResBufSize; - DWORD dwTotalVols = 0; - DWORD dwVolBegin, dwVolEnd; - DWORD dwFlushBegin, dwFlushEnd; - HANDLE hEnum; + CHAR bufMessage[1024]; + UINT i; + DWORD dwServerSize; + DWORD dwRet; + DWORD dwCount; + DWORD dwNetResBufSize; + DWORD dwTotalVols = 0; + DWORD dwVolBegin, dwVolEnd; + DWORD dwFlushBegin, dwFlushEnd; + HANDLE hEnum; LPNETRESOURCE lpNetResBuf, lpnr; - PCHAR pszShareName, pc; + char *pszShareName, *pc; afs_int32 afsRet = 0; if ( lana_OnlyLoopback() ) { diff --git a/src/WINNT/afsd/afsd_init.c b/src/WINNT/afsd/afsd_init.c index bef18a1..b2cc032 100644 --- a/src/WINNT/afsd/afsd_init.c +++ b/src/WINNT/afsd/afsd_init.c @@ -36,6 +36,9 @@ #include "lanahelper.h" #include #include "cm_memmap.h" +#ifdef DEBUG +#include +#endif extern int RXAFSCB_ExecuteRequest(struct rx_call *z_call); extern int RXSTATS_ExecuteRequest(struct rx_call *z_call); @@ -50,16 +53,21 @@ extern afs_int32 cm_BPlusTrees; #endif extern afs_int32 cm_OfflineROIsValid; extern afs_int32 cm_giveUpAllCBs; -extern const char **smb_ExecutableExtensions; +extern const clientchar_t **smb_ExecutableExtensions; osi_log_t *afsd_logp; cm_config_data_t cm_data; -char cm_rootVolumeName[VL_MAXNAMELEN]; +fschar_t cm_rootVolumeName[VL_MAXNAMELEN]; DWORD cm_rootVolumeNameLen; -char cm_mountRoot[1024]; + +fschar_t cm_mountRoot[1024]; DWORD cm_mountRootLen; + +clientchar_t cm_mountRootC[1024]; +DWORD cm_mountRootCLen; + int cm_logChunkSize; int cm_chunkSize; @@ -79,6 +87,7 @@ long cm_HostAddr; unsigned short cm_callbackport = CM_DEFAULT_CALLBACKPORT; char cm_NetbiosName[MAX_NB_NAME_LENGTH] = ""; +clientchar_t cm_NetbiosNameC[MAX_NB_NAME_LENGTH] = _C(""); char cm_CachePath[MAX_PATH]; DWORD cm_ValidateCache = 1; @@ -87,9 +96,9 @@ BOOL reportSessionStartups = FALSE; cm_initparams_v1 cm_initParams; -char *cm_sysName = 0; -unsigned int cm_sysNameCount = 0; -char *cm_sysNameList[MAXNUMSYSNAMES]; +clientchar_t *cm_sysName = 0; +unsigned int cm_sysNameCount = 0; +clientchar_t *cm_sysNameList[MAXNUMSYSNAMES]; DWORD TraceOption = 0; @@ -134,12 +143,6 @@ afsi_log(char *pattern, ...) } } -extern initUpperCaseTable(); -void afsd_initUpperCaseTable() -{ - initUpperCaseTable(); -} - void afsi_start() { @@ -296,10 +299,10 @@ configureBackConnectionHostNames(void) pHostNames, &dwSize) == ERROR_SUCCESS) { for (pName = pHostNames; - (pName - pHostNames < dwSize) && *pName ; + (pName - pHostNames < (int) dwSize) && *pName ; pName += strlen(pName) + 1) { - if ( !cm_stricmp_utf8(pName, cm_NetbiosName) ) { + if ( !stricmp(pName, cm_NetbiosName) ) { bNameFound = TRUE; break; } @@ -562,7 +565,7 @@ int afsd_InitCM(char **reasonP) long ltt, ltto; long rx_nojumbo; long virtualCache = 0; - char rootCellName[256]; + fschar_t rootCellName[256]; struct rx_service *serverp; static struct rx_securityClass *nullServerSecurityClassp; struct hostent *thp; @@ -575,7 +578,6 @@ int afsd_InitCM(char **reasonP) /*int freelanceEnabled;*/ WSADATA WSAjunk; int i; - char *p, *q; int cm_noIPAddr; /* number of client network interfaces */ int cm_IPAddr[CM_MAXINTERFACE_ADDR]; /* client's IP address in host order */ int cm_SubnetMask[CM_MAXINTERFACE_ADDR];/* client's subnet mask in host order*/ @@ -584,7 +586,6 @@ int afsd_InitCM(char **reasonP) WSAStartup(0x0101, &WSAjunk); - afsd_initUpperCaseTable(); init_et_to_sys_error(); /* setup osidebug server at RPC slot 1000 */ @@ -612,7 +613,7 @@ int afsd_InitCM(char **reasonP) /* Look up configuration parameters in Registry */ code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY, - 0, KEY_QUERY_VALUE, &parmKey); + 0, KEY_QUERY_VALUE, &parmKey); if (code != ERROR_SUCCESS) { FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, @@ -820,29 +821,32 @@ int afsd_InitCM(char **reasonP) dummyLen = sizeof(cm_rootVolumeName); code = RegQueryValueEx(parmKey, "RootVolume", NULL, NULL, - cm_rootVolumeName, &dummyLen); + (LPBYTE) cm_rootVolumeName, &dummyLen); if (code == ERROR_SUCCESS) afsi_log("Root volume %s", cm_rootVolumeName); else { - StringCbCopyA(cm_rootVolumeName, sizeof(cm_rootVolumeName), "root.afs"); + cm_FsStrCpy(cm_rootVolumeName, lengthof(cm_rootVolumeName), "root.afs"); afsi_log("Default root volume name root.afs"); } - cm_mountRootLen = sizeof(cm_mountRoot); - code = RegQueryValueEx(parmKey, "MountRoot", NULL, NULL, - cm_mountRoot, &cm_mountRootLen); + cm_mountRootCLen = sizeof(cm_mountRootC); + code = RegQueryValueExW(parmKey, L"MountRoot", NULL, NULL, + (LPBYTE) cm_mountRootC, &cm_mountRootCLen); if (code == ERROR_SUCCESS) { - afsi_log("Mount root %s", cm_mountRoot); - cm_mountRootLen = (DWORD)strlen(cm_mountRoot); + afsi_log("Mount root %S", cm_mountRootC); + cm_mountRootCLen = cm_ClientStrLen(cm_mountRootC); } else { - StringCbCopyA(cm_mountRoot, sizeof(cm_mountRoot), "/afs"); - cm_mountRootLen = 4; + cm_ClientStrCpy(cm_mountRootC, lengthof(cm_mountRootC), _C("/afs")); + cm_mountRootCLen = cm_ClientStrLen(cm_mountRootC); /* Don't log */ } + cm_ClientStringToFsString(cm_mountRootC, -1, cm_mountRoot, lengthof(cm_mountRoot)); + cm_mountRootLen = cm_FsStrLen(cm_mountRoot); + dummyLen = sizeof(buf); code = RegQueryValueEx(parmKey, "CachePath", NULL, ®Type, - buf, &dummyLen); + buf, &dummyLen); if (code == ERROR_SUCCESS && buf[0]) { if (regType == REG_EXPAND_SZ) { dummyLen = ExpandEnvironmentStrings(buf, cm_CachePath, sizeof(cm_CachePath)); @@ -907,47 +911,49 @@ int afsd_InitCM(char **reasonP) } for ( i=0; i < MAXNUMSYSNAMES; i++ ) { - cm_sysNameList[i] = osi_Alloc(MAXSYSNAME); + cm_sysNameList[i] = osi_Alloc(MAXSYSNAME * sizeof(clientchar_t)); cm_sysNameList[i][0] = '\0'; } cm_sysName = cm_sysNameList[0]; - dummyLen = sizeof(buf); - code = RegQueryValueEx(parmKey, "SysName", NULL, NULL, buf, &dummyLen); - if (code != ERROR_SUCCESS || !buf[0]) { + { + clientchar_t *p, *q; + clientchar_t * cbuf = (clientchar_t *) buf; + dummyLen = sizeof(buf); + code = RegQueryValueExW(parmKey, L"SysName", NULL, NULL, (LPBYTE) cbuf, &dummyLen); + if (code != ERROR_SUCCESS || !cbuf[0]) { #if defined(_IA64_) - StringCbCopyA(buf, sizeof(buf), "ia64_win64"); + cm_ClientStrCpy(cbuf, lengthof(buf), _C("ia64_win64")); #elif defined(_AMD64_) - StringCbCopyA(buf, sizeof(buf), "amd64_win64 x86_win32 i386_w2k"); + cm_ClientStrCpy(cbuf, lengthof(buf), _C("amd64_win64 x86_win32 i386_w2k")); #else /* assume x86 32-bit */ - StringCbCopyA(buf, sizeof(buf), "x86_win32 i386_w2k i386_nt40"); + cm_ClientStrCpy(cbuf, lengthof(buf), _C("x86_win32 i386_w2k i386_nt40")); #endif - } - afsi_log("Sys name %s", buf); - - /* breakup buf into individual search string entries */ - for (p = q = buf; p < buf + dummyLen; p++) - { - if (*p == '\0' || isspace(*p)) { - memcpy(cm_sysNameList[cm_sysNameCount],q,p-q); - cm_sysNameList[cm_sysNameCount][p-q] = '\0'; - cm_sysNameCount++; - - do { - if (*p == '\0') - goto done_sysname; - p++; - } while (*p == '\0' || isspace(*p)); - q = p; - p--; + } + afsi_log("Sys name %S", cbuf); + + /* breakup buf into individual search string entries */ + for (p = q = cbuf; p < cbuf + dummyLen; p++) { + if (*p == '\0' || iswspace(*p)) { + memcpy(cm_sysNameList[cm_sysNameCount],q,(p-q) * sizeof(clientchar_t)); + cm_sysNameList[cm_sysNameCount][p-q] = '\0'; + cm_sysNameCount++; + do { + if (*p == '\0') + goto done_sysname; + p++; + } while (*p == '\0' || isspace(*p)); + q = p; + p--; + } } } done_sysname: - StringCbCopyA(cm_sysName, MAXSYSNAME, cm_sysNameList[0]); + cm_ClientStrCpy(cm_sysName, MAXSYSNAME, cm_sysNameList[0]); dummyLen = sizeof(cryptall); code = RegQueryValueEx(parmKey, "SecurityLevel", NULL, NULL, - (BYTE *) &cryptall, &dummyLen); + (BYTE *) &cryptall, &dummyLen); if (code == ERROR_SUCCESS) { afsi_log("SecurityLevel is %s", cryptall?"crypt":"clear"); } else { @@ -1150,28 +1156,27 @@ int afsd_InitCM(char **reasonP) afsi_log("CM BPlusTrees is not supported"); #endif - if ((RegQueryValueEx( parmKey, "PrefetchExecutableExtensions", 0, - ®Type, NULL, &dummyLen) == ERROR_SUCCESS) && + if ((RegQueryValueExW( parmKey, L"PrefetchExecutableExtensions", 0, + ®Type, NULL, &dummyLen) == ERROR_SUCCESS) && (regType == REG_MULTI_SZ)) { - char * pSz; + clientchar_t * pSz; dummyLen += 3; /* in case the source string is not nul terminated */ pSz = malloc(dummyLen); - if ((RegQueryValueEx( parmKey, "PrefetchExecutableExtensions", 0, ®Type, - pSz, &dummyLen) == ERROR_SUCCESS) && + if ((RegQueryValueExW( parmKey, L"PrefetchExecutableExtensions", 0, ®Type, + (LPBYTE) pSz, &dummyLen) == ERROR_SUCCESS) && (regType == REG_MULTI_SZ)) { int cnt; - char * p; + clientchar_t * p; - for (cnt = 0, p = pSz; (p - pSz < dummyLen) && *p; cnt++, p += strlen(p) + 1); + for (cnt = 0, p = pSz; (p - pSz < dummyLen) && *p; cnt++, p += cm_ClientStrLen(p) + 1); - smb_ExecutableExtensions = malloc(sizeof(char *) * (cnt+1)); + smb_ExecutableExtensions = malloc(sizeof(clientchar_t *) * (cnt+1)); - for (cnt = 0, p = pSz; (p - pSz < dummyLen) && *p; cnt++, p += strlen(p) + 1) - { + for (cnt = 0, p = pSz; (p - pSz < dummyLen) && *p; cnt++, p += cm_ClientStrLen(p) + 1) { smb_ExecutableExtensions[cnt] = p; - afsi_log("PrefetchExecutableExtension: \"%s\"", p); + afsi_log("PrefetchExecutableExtension: \"%S\"", p); } smb_ExecutableExtensions[cnt] = NULL; } @@ -1275,6 +1280,8 @@ int afsd_InitCM(char **reasonP) } if ( rx_mtu != -1 ) { + extern void rx_SetMaxMTU(int); + rx_SetMaxMTU(rx_mtu); afsi_log("rx_SetMaxMTU %d successful", rx_mtu); } @@ -1324,7 +1331,7 @@ int afsd_InitCM(char **reasonP) code = cm_GetRootCellName(rootCellName); afsi_log("cm_GetRootCellName code %d, cm_freelanceEnabled= %d, rcn= %s", - code, cm_freelanceEnabled, (code ? "" : rootCellName)); + code, cm_freelanceEnabled, (code ? "" : rootCellName)); if (code != 0 && !cm_freelanceEnabled) { *reasonP = "can't find root cell name in " AFS_CELLSERVDB; @@ -1790,7 +1797,7 @@ void afsd_SetUnhandledExceptionFilter() SetUnhandledExceptionFilter(afsd_ExceptionFilter); #endif } - + #ifdef _DEBUG void afsd_DbgBreakAllocInit() { diff --git a/src/WINNT/afsd/afsd_init.h b/src/WINNT/afsd/afsd_init.h index c022b5d..5678bb3 100644 --- a/src/WINNT/afsd/afsd_init.h +++ b/src/WINNT/afsd/afsd_init.h @@ -20,5 +20,5 @@ void afsd_SetUnhandledExceptionFilter(); extern char cm_HostName[]; extern char cm_NetbiosName[]; - +extern clientchar_t cm_NetbiosNameC[]; diff --git a/src/WINNT/afsd/afsd_service.c b/src/WINNT/afsd/afsd_service.c index 2fe5344..8ca9c11 100644 --- a/src/WINNT/afsd/afsd_service.c +++ b/src/WINNT/afsd/afsd_service.c @@ -14,6 +14,9 @@ #include #include #include +#include "cm_btree.h" +#include "cm_rpc.h" +#include "smb.h" #include @@ -1094,6 +1097,8 @@ afsd_Main(DWORD argc, LPTSTR *argv) HMODULE hAdvApi32; #ifdef _DEBUG + void afsd_DbgBreakAllocInit(); + afsd_DbgBreakAllocInit(); _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF /*| _CRTDBG_CHECK_ALWAYS_DF*/ | _CRTDBG_CHECK_CRT_DF /* | _CRTDBG_DELAY_FREE_MEM_DF */ ); diff --git a/src/WINNT/afsd/cm_btree.c b/src/WINNT/afsd/cm_btree.c index e70fdb3..200525c 100644 --- a/src/WINNT/afsd/cm_btree.c +++ b/src/WINNT/afsd/cm_btree.c @@ -1,5 +1,5 @@ /* - * Copyright 2007 Secure Endpoints Inc. + * Copyright 2007-2008 Secure Endpoints Inc. * * All Rights Reserved. * @@ -15,6 +15,7 @@ #include #include #include "afsd.h" +#include #ifdef USE_BPLUS #include "cm_btree.h" @@ -43,7 +44,7 @@ static void putFreeNode(Tree *B, Nptr self); static void cleanupNodePool(Tree *B); static Nptr descendToLeaf(Tree *B, Nptr curr); -static int getSlot(Tree *B, Nptr curr); +int getSlot(Tree *B, Nptr curr); static int findKey(Tree *B, Nptr curr, int lo, int hi); static int bestMatch(Tree *B, Nptr curr, int slot); @@ -164,7 +165,7 @@ Tree *initBtree(unsigned int poolsz, unsigned int fanout, KeyCmp keyCmp) setcomparekeys(B, keyCmp); #ifdef DEBUG_BTREE - sprintf(B->message, "INIT: B+tree of fanout %d at %10p.\n", fanout, (void *)B); + StringCbPrintfA(B->message, sizeof(B->message), "INIT: B+tree of fanout %d at %10p.\n", fanout, (void *)B); OutputDebugString(B->message); #endif @@ -178,7 +179,7 @@ Tree *initBtree(unsigned int poolsz, unsigned int fanout, KeyCmp keyCmp) void freeBtree(Tree *B) { #ifdef DEBUG_BTREE - sprintf(B->message, "FREE: B+tree at %10p.\n", (void *) B); + StringCbPrintfA(B->message, sizeof(B->message), "FREE: B+tree at %10p.\n", (void *) B); OutputDebugString(B->message); #endif @@ -266,7 +267,7 @@ Nptr bplus_Lookup(Tree *B, keyT key) Nptr leafNode; #ifdef DEBUG_BTREE - sprintf(B->message, "LOOKUP: key %s.\n", key.name); + StringCbPrintfA(B->message, sizeof(B->message), "LOOKUP: key %s.\n", key.name); OutputDebugString(B->message); #endif @@ -286,14 +287,14 @@ Nptr bplus_Lookup(Tree *B, keyT key) dataNode = getnode(leafNode, slot); data = getdatavalue(dataNode); - sprintf(B->message, "LOOKUP: %s found on page %d value (%d.%d.%d).\n", + StringCbPrintfA(B->message, sizeof(B->message), "LOOKUP: %s found on page %d value (%d.%d.%d).\n", key.name, getnodenumber(B, leafNode), data.fid.volume, data.fid.vnode, data.fid.unique); } else - sprintf(B->message, "LOOKUP: not found!\n"); + StringCbPrintfA(B->message, sizeof(B->message), "LOOKUP: not found!\n"); OutputDebugString(B->message); #endif @@ -334,7 +335,7 @@ static Nptr descendToLeaf(Tree *B, Nptr curr) } /******************** find slot for search key *********************/ -static int getSlot(Tree *B, Nptr curr) +int getSlot(Tree *B, Nptr curr) { int slot, entries; @@ -355,7 +356,7 @@ static int findKey(Tree *B, Nptr curr, int lo, int hi) #ifdef DEBUG_BTREE if (findslot == BTERROR) { - sprintf(B->message, "FINDKEY: (lo %d hi %d) Bad key ordering on node %d (0x%p)\n", + StringCbPrintfA(B->message, sizeof(B->message), "FINDKEY: (lo %d hi %d) Bad key ordering on node %d (0x%p)\n", lo, hi, getnodenumber(B, curr), curr); osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message)); } @@ -372,7 +373,7 @@ static int findKey(Tree *B, Nptr curr, int lo, int hi) findslot = findKey(B, curr, mid + 1, hi); break; case BTERROR: - sprintf(B->message, "FINDKEY: (lo %d hi %d) Bad key ordering on node %d (0x%p)\n", + StringCbPrintfA(B->message, sizeof(B->message), "FINDKEY: (lo %d hi %d) Bad key ordering on node %d (0x%p)\n", lo, hi, getnodenumber(B, curr), curr); osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message)); } @@ -380,7 +381,7 @@ static int findKey(Tree *B, Nptr curr, int lo, int hi) if (isleaf(curr) && findslot == 0) { - sprintf(B->message, "FINDKEY: (lo %d hi %d) findslot %d is invalid for leaf nodes, bad key ordering on node %d (0x%p)\n", + StringCbPrintfA(B->message, sizeof(B->message), "FINDKEY: (lo %d hi %d) findslot %d is invalid for leaf nodes, bad key ordering on node %d (0x%p)\n", lo, hi, findslot, getnodenumber(B, curr), curr); osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message)); } @@ -435,7 +436,7 @@ static int bestMatch(Tree *B, Nptr curr, int slot) if (findslot == BTERROR || isleaf(curr) && findslot == 0) { - sprintf(B->message, "BESTMATCH: node %d (0x%p) slot %d diff %d comp %d findslot %d\n", + StringCbPrintfA(B->message, sizeof(B->message), "BESTMATCH: node %d (0x%p) slot %d diff %d comp %d findslot %d\n", getnodenumber(B, curr), curr, slot, diff, comp, findslot); osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message)); } @@ -454,7 +455,7 @@ void insert(Tree *B, keyT key, dataT data) Nptr newNode; #ifdef DEBUG_BTREE - sprintf(B->message, "INSERT: key %s.\n", key.name); + StringCbPrintfA(B->message, sizeof(B->message), "INSERT: key %s.\n", key.name); osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message)); #endif @@ -528,7 +529,7 @@ insertEntry(Tree *B, Nptr currNode, int slot, Nptr sibling, Nptr downPtr) keyT key; #ifdef DEBUG_BTREE - sprintf(B->message, "INSERT: slot %d, down node %d.\n", slot, getnodenumber(B, downPtr)); + StringCbPrintfA(B->message, sizeof(B->message), "INSERT: slot %d, down node %d.\n", slot, getnodenumber(B, downPtr)); osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message)); #endif @@ -732,7 +733,7 @@ void delete(Tree *B, keyT key) Nptr newNode; #ifdef DEBUG_BTREE - sprintf(B->message, "DELETE: key %s.\n", key.name); + StringCbPrintfA(B->message, sizeof(B->message), "DELETE: key %s.\n", key.name); osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message)); #endif @@ -741,7 +742,7 @@ void delete(Tree *B, keyT key) newNode = descendBalance(B, getroot(B), NONODE, NONODE, NONODE, NONODE, NONODE); if (isnode(newNode)) { #ifdef DEBUG_BTREE - sprintf(B->message, "DELETE: collapsing node %d", getnodenumber(B, newNode)); + StringCbPrintfA(B->message, sizeof(B->message), "DELETE: collapsing node %d", getnodenumber(B, newNode)); osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message)); #endif collapseRoot(B, getroot(B), newNode); /* remove root when superfluous */ @@ -755,7 +756,7 @@ collapseRoot(Tree *B, Nptr oldRoot, Nptr newRoot) { #ifdef DEBUG_BTREE - sprintf(B->message, "COLLAPSE: old %d, new %d.\n", getnodenumber(B, oldRoot), getnodenumber(B, newRoot)); + StringCbPrintfA(B->message, sizeof(B->message), "COLLAPSE: old %d, new %d.\n", getnodenumber(B, oldRoot), getnodenumber(B, newRoot)); osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message)); showNode(B, "collapseRoot oldRoot", oldRoot); showNode(B, "collapseRoot newRoot", newRoot); @@ -777,7 +778,7 @@ descendBalance(Tree *B, Nptr curr, Nptr left, Nptr right, Nptr lAnc, Nptr rAnc, int slot = 0, notleft = 0, notright = 0, fewleft = 0, fewright = 0, test = 0; #ifdef DEBUG_BTREE - sprintf(B->message, "descendBalance curr %d, left %d, right %d, lAnc %d, rAnc %d, parent %d\n", + StringCbPrintfA(B->message, sizeof(B->message), "descendBalance curr %d, left %d, right %d, lAnc %d, rAnc %d, parent %d\n", curr ? getnodenumber(B, curr) : -1, left ? getnodenumber(B, left) : -1, right ? getnodenumber(B, right) : -1, @@ -918,7 +919,7 @@ descendBalance(Tree *B, Nptr curr, Nptr left, Nptr right, Nptr lAnc, Nptr rAnc, if (newMe != NONODE) { /* this node removal doesn't consider duplicates */ #ifdef DEBUG_BTREE - sprintf(B->message, "descendBalance DELETE: slot %d, node %d.\n", slot, getnodenumber(B, curr)); + StringCbPrintfA(B->message, sizeof(B->message), "descendBalance DELETE: slot %d, node %d.\n", slot, getnodenumber(B, curr)); osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message)); #endif @@ -972,7 +973,7 @@ descendBalance(Tree *B, Nptr curr, Nptr left, Nptr right, Nptr lAnc, Nptr rAnc, } #ifdef DEBUG_BTREE - sprintf(B->message, "descendBalance returns %d\n", getnodenumber(B, newNode)); + StringCbPrintfA(B->message, sizeof(B->message), "descendBalance returns %d\n", getnodenumber(B, newNode)); osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message)); #endif return newNode; @@ -1004,7 +1005,7 @@ merge(Tree *B, Nptr left, Nptr right, Nptr anchor) int x, y, z; #ifdef DEBUG_BTREE - sprintf(B->message, "MERGE: left %d, right %d.\n", getnodenumber(B, left), getnodenumber(B, right)); + StringCbPrintfA(B->message, sizeof(B->message), "MERGE: left %d, right %d.\n", getnodenumber(B, left), getnodenumber(B, right)); osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message)); showNode(B, "pre-merge anchor", anchor); showNode(B, "pre-merge left", left); @@ -1061,7 +1062,7 @@ shift(Tree *B, Nptr left, Nptr right, Nptr anchor) int i, x, y, z; #ifdef DEBUG_BTREE - sprintf(B->message, "SHIFT: left %d, right %d, anchor %d.\n", + StringCbPrintfA(B->message, sizeof(B->message), "SHIFT: left %d, right %d, anchor %d.\n", getnodenumber(B, left), getnodenumber(B, right), getnodenumber(B, anchor)); @@ -1162,7 +1163,7 @@ shift(Tree *B, Nptr left, Nptr right, Nptr anchor) setmergepath(B, NONODE); #ifdef DEBUG_BTREE - sprintf(B->message, "SHIFT: left %d, right %d.\n", getnodenumber(B, left), getnodenumber(B, right)); + StringCbPrintfA(B->message, sizeof(B->message), "SHIFT: left %d, right %d.\n", getnodenumber(B, left), getnodenumber(B, right)); osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message)); showNode(B, "post-shift anchor", anchor); showNode(B, "post-shift left", left); @@ -1192,7 +1193,7 @@ _pushentry(Nptr node, int entry, int offset) if (entry == 0) DebugBreak(); #endif - getkey(node,entry + offset).name = strdup(getkey(node,entry).name); + getkey(node,entry + offset).name = cm_NormStrDup(getkey(node,entry).name); #ifdef DEBUG_BTREE if ( getnode(node, entry) == NONODE ) DebugBreak(); @@ -1205,7 +1206,7 @@ _pullentry(Nptr node, int entry, int offset) { if (getkey(node,entry).name != NULL) free(getkey(node,entry).name); - getkey(node,entry).name = strdup(getkey(node,entry + offset).name); + getkey(node,entry).name = cm_NormStrDup(getkey(node,entry + offset).name); #ifdef DEBUG_BTREE if ( getnode(node, entry + offset) == NONODE ) DebugBreak(); @@ -1218,7 +1219,7 @@ _xferentry(Nptr srcNode, int srcEntry, Nptr destNode, int destEntry) { if (getkey(destNode,destEntry).name != NULL) free(getkey(destNode,destEntry).name); - getkey(destNode,destEntry).name = strdup(getkey(srcNode,srcEntry).name); + getkey(destNode,destEntry).name = cm_NormStrDup(getkey(srcNode,srcEntry).name); #ifdef DEBUG_BTREE if ( getnode(srcNode, srcEntry) == NONODE ) DebugBreak(); @@ -1231,7 +1232,7 @@ _setentry(Nptr node, int entry, keyT key, Nptr downNode) { if (getkey(node,entry).name != NULL) free(getkey(node,entry).name); - getkey(node,entry).name = strdup(key.name); + getkey(node,entry).name = cm_NormStrDup(key.name); #ifdef DEBUG_BTREE if ( downNode == NONODE ) DebugBreak(); @@ -1289,13 +1290,13 @@ cleanupNodePool(Tree *B) free(getdatakey(node).name); getdatakey(node).name = NULL; } - if ( getdatavalue(node).longname ) { - free(getdatavalue(node).longname); - getdatavalue(node).longname = NULL; + if ( getdatavalue(node).cname ) { + free(getdatavalue(node).cname); + getdatavalue(node).cname = NULL; } - if ( getdatavalue(node).origname ) { - free(getdatavalue(node).origname); - getdatavalue(node).origname = NULL; + if ( getdatavalue(node).fsname ) { + free(getdatavalue(node).fsname); + getdatavalue(node).fsname = NULL; } } else { /* data node */ for ( j=1; j<=getfanout(B); j++ ) { @@ -1345,8 +1346,10 @@ putFreeNode(Tree *B, Nptr node) if (isdata(node)) { if ( getdatakey(node).name ) free(getdatakey(node).name); - if ( getdatavalue(node).longname ) - free(getdatavalue(node).longname); + if ( getdatavalue(node).cname ) + free(getdatavalue(node).cname); + if ( getdatavalue(node).fsname ) + free(getdatavalue(node).fsname); } else { /* data node */ for ( i=1; i<=getfanout(B); i++ ) { if (getkey(node, i).name) @@ -1368,7 +1371,7 @@ getDataNode(Tree *B, keyT key, dataT data) Nptr newNode = getFreeNode(B); setflag(newNode, isDATA); - getdatakey(newNode).name = strdup(key.name); + getdatakey(newNode).name = cm_NormStrDup(key.name); getdatavalue(newNode) = data; getdatanext(newNode) = NONODE; @@ -1386,61 +1389,61 @@ void showNode(Tree *B, const char * where, Nptr n) { int x; - sprintf(B->message, "- -- -- -- -- -- -- -- -- -- -- -- -\n"); + StringCbPrintfA(B->message, sizeof(B->message), "- -- -- -- -- -- -- -- -- -- -- -- -\n"); osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message)); - sprintf(B->message, "| %-20s |\n", where); + StringCbPrintfA(B->message, sizeof(B->message), "| %-20s |\n", where); osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message)); - sprintf(B->message, "| node %6d ", getnodenumber(B, n)); + StringCbPrintfA(B->message, sizeof(B->message), "| node %6d ", getnodenumber(B, n)); osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message)); - sprintf(B->message, " magic %4x |\n", getmagic(n)); + StringCbPrintfA(B->message, sizeof(B->message), " magic %4x |\n", getmagic(n)); osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message)); - sprintf(B->message, "- -- -- -- -- -- -- -- -- -- -- -- -\n"); + StringCbPrintfA(B->message, sizeof(B->message), "- -- -- -- -- -- -- -- -- -- -- -- -\n"); osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message)); - sprintf(B->message, "| flags %1d%1d%1d%1d ", isfew(n), isfull(n), isroot(n), isleaf(n)); + StringCbPrintfA(B->message, sizeof(B->message), "| flags %1d%1d%1d%1d ", isfew(n), isfull(n), isroot(n), isleaf(n)); osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message)); - sprintf(B->message, "| keys = %5d ", numentries(n)); + StringCbPrintfA(B->message, sizeof(B->message), "| keys = %5d ", numentries(n)); osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message)); - sprintf(B->message, "| node = %6d |\n", getnodenumber(B, getfirstnode(n))); + StringCbPrintfA(B->message, sizeof(B->message), "| node = %6d |\n", getnodenumber(B, getfirstnode(n))); osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message)); for (x = 1; x <= numentries(n); x++) { - sprintf(B->message, "| entry %6d ", x); + StringCbPrintfA(B->message, sizeof(B->message), "| entry %6d ", x); osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message)); - sprintf(B->message, "| key = %6s ", getkey(n, x).name); + StringCbPrintfA(B->message, sizeof(B->message), "| key = %6s ", getkey(n, x).name); osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message)); - sprintf(B->message, "| node = %6d |\n", getnodenumber(B, getnode(n, x))); + StringCbPrintfA(B->message, sizeof(B->message), "| node = %6d |\n", getnodenumber(B, getnode(n, x))); osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message)); } - sprintf(B->message, "- -- -- -- -- -- -- -- -- -- -- -- -\n"); + StringCbPrintfA(B->message, sizeof(B->message), "- -- -- -- -- -- -- -- -- -- -- -- -\n"); osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message)); } /****************** B+tree class variable printer ******************/ void showBtree(Tree *B) { - sprintf(B->message, "- -- -- -- -- -- -\n"); + StringCbPrintfA(B->message, sizeof(B->message), "- -- -- -- -- -- -\n"); osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message)); - sprintf(B->message, "| B+tree %10p |\n", (void *) B); + StringCbPrintfA(B->message, sizeof(B->message), "| B+tree %10p |\n", (void *) B); osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message)); - sprintf(B->message, "- -- -- -- -- -- -\n"); + StringCbPrintfA(B->message, sizeof(B->message), "- -- -- -- -- -- -\n"); osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message)); - sprintf(B->message, "| root %6d |\n", getnodenumber(B, getroot(B))); + StringCbPrintfA(B->message, sizeof(B->message), "| root %6d |\n", getnodenumber(B, getroot(B))); osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message)); - sprintf(B->message, "| leaf %6d |\n", getnodenumber(B, getleaf(B))); + StringCbPrintfA(B->message, sizeof(B->message), "| leaf %6d |\n", getnodenumber(B, getleaf(B))); osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message)); - sprintf(B->message, "| fanout %3d |\n", getfanout(B) + 1); + StringCbPrintfA(B->message, sizeof(B->message), "| fanout %3d |\n", getfanout(B) + 1); osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message)); - sprintf(B->message, "| minfanout %3d |\n", getminfanout(B, getroot(B)) + 1); + StringCbPrintfA(B->message, sizeof(B->message), "| minfanout %3d |\n", getminfanout(B, getroot(B)) + 1); osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message)); - sprintf(B->message, "| height %3d |\n", gettreeheight(B)); + StringCbPrintfA(B->message, sizeof(B->message), "| height %3d |\n", gettreeheight(B)); osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message)); - sprintf(B->message, "| freenode %6d |\n", getnodenumber(B, getfirstfreenode(B))); + StringCbPrintfA(B->message, sizeof(B->message), "| freenode %6d |\n", getnodenumber(B, getfirstfreenode(B))); osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message)); - sprintf(B->message, "| theKey %6s |\n", getfunkey(B).name); + StringCbPrintfA(B->message, sizeof(B->message), "| theKey %6s |\n", getfunkey(B).name); osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message)); - sprintf(B->message, "| theData %d.%d.%d |\n", getfundata(B).volume, + StringCbPrintfA(B->message, sizeof(B->message), "| theData %d.%d.%d |\n", getfundata(B).volume, getfundata(B).vnode, getfundata(B).unique); osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message)); - sprintf(B->message, "- -- -- -- -- -- -\n"); + StringCbPrintfA(B->message, sizeof(B->message), "- -- -- -- -- -- -\n"); osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message)); } @@ -1452,7 +1455,7 @@ listBtreeNodes(Tree *B, const char * parent_desc, Nptr node) dataT data; if (isntnode(node)) { - sprintf(B->message, "%s - NoNode!!!\n"); + StringCbPrintfA(B->message, sizeof(B->message), "%s - NoNode!!!\n"); osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message)); return; } @@ -1460,7 +1463,7 @@ listBtreeNodes(Tree *B, const char * parent_desc, Nptr node) if (!isnode(node)) { data = getdatavalue(node); - sprintf(B->message, "%s - data node %d (%d.%d.%d)\n", + StringCbPrintfA(B->message, sizeof(B->message), "%s - data node %d (%d.%d.%d)\n", parent_desc, getnodenumber(B, node), data.fid.volume, data.fid.vnode, data.fid.unique); osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message)); @@ -1469,7 +1472,7 @@ listBtreeNodes(Tree *B, const char * parent_desc, Nptr node) showNode(B, parent_desc, node); if ( isinternal(node) || isroot(node) ) { - sprintf(thisnode, "parent %6d", getnodenumber(B , node)); + StringCbPrintfA(thisnode, sizeof(thisnode), "parent %6d", getnodenumber(B , node)); osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message)); for ( i= isinternal(node) ? 0 : 1; i <= numentries(node); i++ ) { @@ -1483,24 +1486,24 @@ void listBtreeValues(Tree *B, Nptr n, int num) { int slot; - keyT prev = {""}; + keyT prev = {L""}; dataT data; for (slot = 1; (n != NONODE) && num && numentries(n); num--) { if (comparekeys(B)(getkey(n, slot),prev, 0) < 0) { - sprintf(B->message, "BOMB %8s\n", getkey(n, slot).name); + StringCbPrintfA(B->message, sizeof(B->message), "BOMB %8s\n", getkey(n, slot).name); osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message)); DebugBreak(); } prev = getkey(n, slot); data = getdatavalue(getnode(n, slot)); - sprintf(B->message, "%8s (%d.%d.%d)\n", + StringCbPrintfA(B->message, sizeof(B->message), "%8S (%d.%d.%d)\n", prev.name, data.fid.volume, data.fid.vnode, data.fid.unique); osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message)); if (++slot > numentries(n)) n = getnextnode(n), slot = 1; - } - sprintf(B->message, "\n\n"); + } + StringCbPrintfA(B->message, sizeof(B->message), "\n\n"); osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message)); } @@ -1518,11 +1521,11 @@ findAllBtreeValues(Tree *B) int num = -1; Nptr n = getleaf(B), l; int slot; - keyT prev = {""}; + keyT prev = {L""}; for (slot = 1; (n != NONODE) && num && numentries(n); num--) { if (comparekeys(B)(getkey(n, slot),prev, 0) < 0) { - sprintf(B->message,"BOMB %8s\n", getkey(n, slot).name); + StringCbPrintfA(B->message, sizeof(B->message),"BOMB %8s\n", getkey(n, slot).name); osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message)); #ifdef DEBUG_BTREE DebugBreak(); @@ -1532,9 +1535,9 @@ findAllBtreeValues(Tree *B) l = bplus_Lookup(B, prev); if ( l != n ){ if (l == NONODE) - sprintf(B->message,"BOMB %8s cannot be found\n", prev.name); + StringCbPrintfA(B->message, sizeof(B->message),"BOMB %8S cannot be found\n", prev.name); else - sprintf(B->message,"BOMB lookup(%8s) finds wrong node\n", prev.name); + StringCbPrintfA(B->message, sizeof(B->message),"BOMB lookup(%8S) finds wrong node\n", prev.name); osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, B->message)); #ifdef DEBUG_BTREE DebugBreak(); @@ -1556,26 +1559,27 @@ findAllBtreeValues(Tree *B) * match. Otherwise, the search order might be considered * to be inconsistent when the EXACT_MATCH flag is set. */ -static int -compareKeys(keyT key1, keyT key2, int flags) +int +cm_BPlusCompareNormalizedKeys(keyT key1, keyT key2, int flags) { int comp; - comp = cm_stricmp_utf8(key1.name, key2.name); + comp = cm_NormStrCmpI(key1.name, key2.name); if (comp == 0 && (flags & EXACT_MATCH)) - comp = strcmp(key1.name, key2.name); + comp = cm_NormStrCmp(key1.name, key2.name); return (comp < 0 ? -1 : (comp > 0 ? 1 : 0)); } int -cm_BPlusDirLookupOriginalName(cm_dirOp_t * op, char * entry, - char ** originalNameRetp) +cm_BPlusDirLookupOriginalName(cm_dirOp_t * op, clientchar_t *centry, + fschar_t **fsnameRetp) { int rc = EINVAL; - keyT key = {entry}; + keyT key = {NULL}; Nptr leafNode = NONODE; LARGE_INTEGER start, end; - char * originalName = NULL; + fschar_t * fsname = NULL; + normchar_t * entry = NULL; if (op->scp->dirBplus == NULL || op->dataVersion != op->scp->dirDataVersion) { @@ -1583,6 +1587,9 @@ cm_BPlusDirLookupOriginalName(cm_dirOp_t * op, char * entry, goto done; } + entry = cm_ClientStringToNormStringAlloc(centry, -1, NULL); + key.name = entry; + lock_AssertAny(&op->scp->dirlock); QueryPerformanceCounter(&start); @@ -1618,11 +1625,11 @@ cm_BPlusDirLookupOriginalName(cm_dirOp_t * op, char * entry, } if (exact) { - originalName = getdatavalue(dataNode).origname; + fsname = getdatavalue(dataNode).fsname; rc = 0; bplus_lookup_hits++; } else if (count == 1) { - originalName = getdatavalue(firstDataNode).origname; + fsname = getdatavalue(firstDataNode).fsname; rc = CM_ERROR_INEXACT_MATCH; bplus_lookup_hits_inexact++; } else { @@ -1634,14 +1641,17 @@ cm_BPlusDirLookupOriginalName(cm_dirOp_t * op, char * entry, bplus_lookup_misses++; } - if (originalName) - *originalNameRetp = strdup(originalName); + if (fsname) + *fsnameRetp = cm_FsStrDup(fsname); QueryPerformanceCounter(&end); bplus_lookup_time += (end.QuadPart - start.QuadPart); done: + if (entry) + free(entry); + return rc; } @@ -1655,10 +1665,11 @@ cm_BPlusDirLookupOriginalName(cm_dirOp_t * op, char * entry, op->scp->dirlock is read locked */ int -cm_BPlusDirLookup(cm_dirOp_t * op, char *entry, cm_fid_t * cfid) +cm_BPlusDirLookup(cm_dirOp_t * op, clientchar_t * centry, cm_fid_t * cfid) { int rc = EINVAL; - keyT key = {entry}; + normchar_t * entry = NULL; + keyT key = {NULL}; Nptr leafNode = NONODE; LARGE_INTEGER start, end; @@ -1668,6 +1679,9 @@ cm_BPlusDirLookup(cm_dirOp_t * op, char *entry, cm_fid_t * cfid) goto done; } + entry = cm_ClientStringToNormStringAlloc(centry, -1, NULL); + key.name = entry; + lock_AssertAny(&op->scp->dirlock); QueryPerformanceCounter(&start); @@ -1724,6 +1738,9 @@ cm_BPlusDirLookup(cm_dirOp_t * op, char *entry, cm_fid_t * cfid) bplus_lookup_time += (end.QuadPart - start.QuadPart); done: + if (entry) + free(entry); + return rc; } @@ -1735,13 +1752,13 @@ cm_BPlusDirLookup(cm_dirOp_t * op, char *entry, cm_fid_t * cfid) On exit: op->scp->dirlock is write locked */ -long cm_BPlusDirCreateEntry(cm_dirOp_t * op, char *entry, cm_fid_t * cfid) +long cm_BPlusDirCreateEntry(cm_dirOp_t * op, clientchar_t * entry, cm_fid_t * cfid) { long rc = 0; - keyT key = {entry}; + keyT key = {NULL}; dataT data; LARGE_INTEGER start, end; - char shortName[13]; + normchar_t * normalizedName = NULL; if (op->scp->dirBplus == NULL || op->dataVersion != op->scp->dirDataVersion) { @@ -1749,26 +1766,36 @@ long cm_BPlusDirCreateEntry(cm_dirOp_t * op, char *entry, cm_fid_t * cfid) goto done; } + normalizedName = cm_ClientStringToNormStringAlloc(entry, -1, NULL); + key.name = normalizedName; lock_AssertWrite(&op->scp->dirlock); cm_SetFid(&data.fid, cfid->cell, cfid->volume, cfid->vnode, cfid->unique); - data.longname = NULL; - data.origname = NULL; + data.cname = cm_ClientStrDup(entry); + data.fsname = cm_ClientStringToFsStringAlloc(entry, -1, NULL); + data.shortform = FALSE; QueryPerformanceCounter(&start); bplus_create_entry++; insert(op->scp->dirBplus, key, data); + if (!cm_Is8Dot3(entry)) { cm_dirFid_t dfid; + clientchar_t wshortName[13]; + dfid.vnode = htonl(data.fid.vnode); dfid.unique = htonl(data.fid.unique); - cm_Gen8Dot3NameInt(entry, &dfid, shortName, NULL); + cm_Gen8Dot3NameIntW(entry, &dfid, wshortName, NULL); + + key.name = wshortName; + + data.cname = cm_ClientStrDup(entry); + data.fsname = cm_ClientStringToFsStringAlloc(entry, -1, NULL); + data.shortform = TRUE; - key.name = shortName; - data.longname = strdup(entry); insert(op->scp->dirBplus, key, data); } @@ -1778,6 +1805,9 @@ long cm_BPlusDirCreateEntry(cm_dirOp_t * op, char *entry, cm_fid_t * cfid) done: + if (normalizedName != NULL) + free(normalizedName); + return rc; } @@ -1788,12 +1818,13 @@ long cm_BPlusDirCreateEntry(cm_dirOp_t * op, char *entry, cm_fid_t * cfid) On exit: op->scp->dirlock is write locked */ -int cm_BPlusDirDeleteEntry(cm_dirOp_t * op, char *entry) +int cm_BPlusDirDeleteEntry(cm_dirOp_t * op, clientchar_t *centry) { long rc = 0; - keyT key = {entry}; + keyT key = {NULL}; Nptr leafNode = NONODE; LARGE_INTEGER start, end; + normchar_t * normalizedEntry = NULL; if (op->scp->dirBplus == NULL || op->dataVersion != op->scp->dirDataVersion) { @@ -1801,6 +1832,9 @@ int cm_BPlusDirDeleteEntry(cm_dirOp_t * op, char *entry) goto done; } + normalizedEntry = cm_ClientStringToNormStringAlloc(centry, -1, NULL); + key.name = normalizedEntry; + lock_AssertWrite(&op->scp->dirlock); QueryPerformanceCounter(&start); @@ -1808,10 +1842,10 @@ int cm_BPlusDirDeleteEntry(cm_dirOp_t * op, char *entry) bplus_remove_entry++; if (op->scp->dirBplus) { - if (!cm_Is8Dot3(entry)) { + if (!cm_Is8Dot3(centry)) { cm_dirFid_t dfid; cm_fid_t fid; - char shortName[13]; + clientchar_t shortName[13]; leafNode = bplus_Lookup(op->scp->dirBplus, key); if (leafNode != NONODE) { @@ -1858,7 +1892,7 @@ int cm_BPlusDirDeleteEntry(cm_dirOp_t * op, char *entry) if (rc != CM_ERROR_AMBIGUOUS_FILENAME) { dfid.vnode = htonl(fid.vnode); dfid.unique = htonl(fid.unique); - cm_Gen8Dot3NameInt(entry, &dfid, shortName, NULL); + cm_Gen8Dot3NameIntW(centry, &dfid, shortName, NULL); /* delete first the long name and then the short name */ delete(op->scp->dirBplus, key); @@ -1866,7 +1900,8 @@ int cm_BPlusDirDeleteEntry(cm_dirOp_t * op, char *entry) delete(op->scp->dirBplus, key); } } else { - char * longname = NULL; + clientchar_t * cname = NULL; + /* We need to lookup the 8dot3 name to determine what the * matching long name is */ @@ -1902,10 +1937,10 @@ int cm_BPlusDirDeleteEntry(cm_dirOp_t * op, char *entry) } if (exact) { - longname = getdatavalue(dataNode).longname; + cname = getdatavalue(dataNode).cname; rc = 0; } else if (count == 1) { - longname = getdatavalue(firstDataNode).longname; + cname = getdatavalue(firstDataNode).cname; rc = CM_ERROR_INEXACT_MATCH; } else { rc = CM_ERROR_AMBIGUOUS_FILENAME; @@ -1913,11 +1948,16 @@ int cm_BPlusDirDeleteEntry(cm_dirOp_t * op, char *entry) } if (rc != CM_ERROR_AMBIGUOUS_FILENAME) { - if (longname) { - key.name = longname; + if (cname) { + normchar_t * longNName = cm_NormalizeStringAlloc(cname, -1, NULL); + + key.name = longNName; delete(op->scp->dirBplus, key); - key.name = entry; + key.name = normalizedEntry; + + free(longNName); } + delete(op->scp->dirBplus, key); } } @@ -1928,6 +1968,9 @@ int cm_BPlusDirDeleteEntry(cm_dirOp_t * op, char *entry) bplus_remove_time += (end.QuadPart - start.QuadPart); done: + if (normalizedEntry) + free(normalizedEntry); + return rc; } @@ -1936,39 +1979,47 @@ static int cm_BPlusDirFoo(struct cm_scache *scp, struct cm_dirEntry *dep, void *dummy, osi_hyper_t *entryOffsetp) { - keyT key = {dep->name}; + keyT key = {NULL}; dataT data; - char shortName[13]; - long normalized_len; - char *normalized_name=NULL; - cm_SetFid(&data.fid, scp->fid.cell, scp->fid.volume, ntohl(dep->fid.vnode), ntohl(dep->fid.unique)); - data.longname = NULL; - data.origname = NULL; - - normalized_len = cm_NormalizeUtf8String(dep->name, -1, NULL, 0); - if (normalized_len) - normalized_name = malloc(normalized_len); + normchar_t *normalized_name=NULL; + + cm_SetFid(&data.fid, scp->fid.cell, scp->fid.volume, + ntohl(dep->fid.vnode), ntohl(dep->fid.unique)); + data.cname = NULL; + data.fsname = NULL; + + normalized_name = cm_FsStringToNormStringAlloc(dep->name, -1, NULL); + if (normalized_name) { - cm_NormalizeUtf8String(dep->name, -1, normalized_name, normalized_len); key.name = normalized_name; - if (strcmp(normalized_name, dep->name)) - data.origname = strdup(dep->name); } else { - key.name = dep->name; +#ifdef DEBUG + DebugBreak(); +#endif + return 0; } + data.cname = cm_FsStringToClientStringAlloc(dep->name, -1, NULL); + data.fsname = cm_FsStrDup(dep->name); + data.shortform = FALSE; + /* the Write lock is held in cm_BPlusDirBuildTree() */ insert(scp->dirBplus, key, data); - if (!cm_Is8Dot3(dep->name)) { + + if (!cm_Is8Dot3(data.cname)) { cm_dirFid_t dfid; + wchar_t wshortName[13]; + dfid.vnode = dep->fid.vnode; dfid.unique = dep->fid.unique; - cm_Gen8Dot3NameInt(dep->name, &dfid, shortName, NULL); + cm_Gen8Dot3NameIntW(data.cname, &dfid, wshortName, NULL); + + key.name = wshortName; + data.cname = cm_FsStringToClientStringAlloc(dep->name, -1, NULL); + data.fsname = cm_FsStrDup(dep->name); + data.shortform = TRUE; - data.longname = strdup(key.name); - data.origname = NULL; - key.name = shortName; insert(scp->dirBplus, key, data); } @@ -2001,7 +2052,7 @@ long cm_BPlusDirBuildTree(cm_scache_t *scp, cm_user_t *userp, cm_req_t* reqp) bplus_build_tree++; if (scp->dirBplus == NULL) { - scp->dirBplus = initBtree(64, MAX_FANOUT, compareKeys); + scp->dirBplus = initBtree(64, MAX_FANOUT, cm_BPlusCompareNormalizedKeys); } if (scp->dirBplus == NULL) { rc = ENOMEM; @@ -2026,34 +2077,34 @@ int cm_MemDumpBPlusStats(FILE *outputFile, char *cookie, int lock) int zilch; char output[128]; - sprintf(output, "%s - B+ Lookup Hits: %-8d\r\n", cookie, bplus_lookup_hits); + StringCbPrintfA(output, sizeof(output), "%s - B+ Lookup Hits: %-8d\r\n", cookie, bplus_lookup_hits); WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL); - sprintf(output, "%s - Inexact Hits: %-8d\r\n", cookie, bplus_lookup_hits_inexact); + StringCbPrintfA(output, sizeof(output), "%s - Inexact Hits: %-8d\r\n", cookie, bplus_lookup_hits_inexact); WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL); - sprintf(output, "%s - Ambiguous Hits: %-8d\r\n", cookie, bplus_lookup_ambiguous); + StringCbPrintfA(output, sizeof(output), "%s - Ambiguous Hits: %-8d\r\n", cookie, bplus_lookup_ambiguous); WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL); - sprintf(output, "%s - Misses: %-8d\r\n", cookie, bplus_lookup_misses); + StringCbPrintfA(output, sizeof(output), "%s - Misses: %-8d\r\n", cookie, bplus_lookup_misses); WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL); - sprintf(output, "%s - Create: %-8d\r\n", cookie, bplus_create_entry); + StringCbPrintfA(output, sizeof(output), "%s - Create: %-8d\r\n", cookie, bplus_create_entry); WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL); - sprintf(output, "%s - Remove: %-8d\r\n", cookie, bplus_remove_entry); + StringCbPrintfA(output, sizeof(output), "%s - Remove: %-8d\r\n", cookie, bplus_remove_entry); WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL); - sprintf(output, "%s - Build Tree: %-8d\r\n", cookie, bplus_build_tree); + StringCbPrintfA(output, sizeof(output), "%s - Build Tree: %-8d\r\n", cookie, bplus_build_tree); WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL); - sprintf(output, "%s - Free Tree: %-8d\r\n", cookie, bplus_free_tree); + StringCbPrintfA(output, sizeof(output), "%s - Free Tree: %-8d\r\n", cookie, bplus_free_tree); WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL); - sprintf(output, "%s - DV Error: %-8d\r\n", cookie, bplus_dv_error); + StringCbPrintfA(output, sizeof(output), "%s - DV Error: %-8d\r\n", cookie, bplus_dv_error); WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL); - sprintf(output, "%s - B+ Time Lookup: %-16I64d\r\n", cookie, bplus_lookup_time); + StringCbPrintfA(output, sizeof(output), "%s - B+ Time Lookup: %-16I64d\r\n", cookie, bplus_lookup_time); WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL); - sprintf(output, "%s - Create: %-16I64d\r\n", cookie, bplus_create_time); + StringCbPrintfA(output, sizeof(output), "%s - Create: %-16I64d\r\n", cookie, bplus_create_time); WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL); - sprintf(output, "%s - Remove: %-16I64d\r\n", cookie, bplus_remove_time); + StringCbPrintfA(output, sizeof(output), "%s - Remove: %-16I64d\r\n", cookie, bplus_remove_time); WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL); - sprintf(output, "%s - Build: %-16I64d\r\n", cookie, bplus_build_time); + StringCbPrintfA(output, sizeof(output), "%s - Build: %-16I64d\r\n", cookie, bplus_build_time); WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL); - sprintf(output, "%s - Free: %-16I64d\r\n", cookie, bplus_free_time); + StringCbPrintfA(output, sizeof(output), "%s - Free: %-16I64d\r\n", cookie, bplus_free_time); WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL); return(0); @@ -2096,7 +2147,7 @@ cm_BPlusEnumAlloc(afs_uint32 entries) long cm_BPlusDirEnumerate(cm_scache_t *scp, afs_uint32 locked, - char * maskp, cm_direnum_t **enumpp) + clientchar_t * maskp, cm_direnum_t **enumpp) { afs_uint32 count = 0, slot, numentries; Nptr leafNode = NONODE, nextLeafNode; @@ -2123,16 +2174,17 @@ cm_BPlusDirEnumerate(cm_scache_t *scp, afs_uint32 locked, firstDataNode = getnode(leafNode, slot); for ( dataNode = firstDataNode; dataNode; dataNode = nextDataNode) { + + /* There can be two data nodes for one file. One for + the long name and one for the short name. We only + include one of these for the enumeration */ + if (maskp == NULL) { - /* name is in getdatakey(dataNode) */ - if (getdatavalue(dataNode).longname != NULL || - cm_Is8Dot3(getdatakey(dataNode).name)) + if (!getdatavalue(dataNode).shortform) count++; } else { - if (cm_Is8Dot3(getdatakey(dataNode).name) && - smb_V3MatchMask(getdatakey(dataNode).name, maskp, CM_FLAG_CASEFOLD) || - getdatavalue(dataNode).longname == NULL && - smb_V3MatchMask(getdatavalue(dataNode).longname, maskp, CM_FLAG_CASEFOLD)) + if (!getdatavalue(dataNode).shortform && + cm_MatchMask(getdatavalue(dataNode).cname, maskp, CM_FLAG_CASEFOLD)) count++; } nextDataNode = getdatanext(dataNode); @@ -2140,9 +2192,9 @@ cm_BPlusDirEnumerate(cm_scache_t *scp, afs_uint32 locked, } nextLeafNode = getnextnode(leafNode); - } + } - sprintf(buffer, "BPlusTreeEnumerate count = %d", count); + StringCbPrintfA(buffer, sizeof(buffer), "BPlusTreeEnumerate count = %d", count); osi_Log1(afsd_logp, "BPlus: %s", osi_LogSaveString(afsd_logp, buffer)); /* Allocate the enumeration object */ @@ -2152,55 +2204,53 @@ cm_BPlusDirEnumerate(cm_scache_t *scp, afs_uint32 locked, rc = ENOMEM; goto done; } - - /* Copy the name and fid for each longname entry into the enumeration */ + + /* Copy the name and fid for each cname entry into the enumeration */ for (count = 0, leafNode = getleaf(scp->dirBplus); leafNode; leafNode = nextLeafNode) { for ( slot = 1, numentries = numentries(leafNode); slot <= numentries; slot++) { firstDataNode = getnode(leafNode, slot); for ( dataNode = firstDataNode; dataNode; dataNode = nextDataNode) { - char * name; - int hasShortName; + clientchar_t * name; int includeIt = 0; if (maskp == NULL) { - if (getdatavalue(dataNode).longname != NULL || - cm_Is8Dot3(getdatakey(dataNode).name)) - { + if (!getdatavalue(dataNode).shortform) { includeIt = 1; } } else { - if (cm_Is8Dot3(getdatakey(dataNode).name) && - smb_V3MatchMask(getdatakey(dataNode).name, maskp, CM_FLAG_CASEFOLD) || - getdatavalue(dataNode).longname == NULL && - smb_V3MatchMask(getdatavalue(dataNode).longname, maskp, CM_FLAG_CASEFOLD)) - { + if (!getdatavalue(dataNode).shortform && + cm_MatchMask(getdatavalue(dataNode).cname, maskp, CM_FLAG_CASEFOLD)) { includeIt = 1; } } if (includeIt) { - if (getdatavalue(dataNode).longname) { - name = strdup(getdatavalue(dataNode).longname); - hasShortName = 1; - } else { - name = strdup(getdatakey(dataNode).name); - hasShortName = 0; - } + name = cm_ClientStrDup(getdatavalue(dataNode).cname); if (name == NULL) { osi_Log0(afsd_logp, "cm_BPlusDirEnumerate strdup failed"); rc = ENOMEM; goto done; } + enump->entry[count].name = name; enump->entry[count].fid = getdatavalue(dataNode).fid; - if (hasShortName) - strncpy(enump->entry[count].shortName, getdatakey(dataNode).name, - sizeof(enump->entry[count].shortName)); - else - enump->entry[count].shortName[0] = '\0'; + + if (!cm_Is8Dot3(name)) { + cm_dirFid_t dfid; + + dfid.vnode = htonl(getdatavalue(dataNode).fid.vnode); + dfid.unique = htonl(getdatavalue(dataNode).fid.unique); + + cm_Gen8Dot3NameIntW(name, &dfid, enump->entry[count].shortName, NULL); + } else { + StringCbCopyW(enump->entry[count].shortName, + sizeof(enump->entry[count].shortName), + name); + } + count++; } nextDataNode = getdatanext(dataNode); @@ -2315,7 +2365,7 @@ cm_BPlusDirEnumTest(cm_scache_t * dscp, afs_uint32 locked) cm_ReleaseSCache(scp); } - sprintf(buffer, "'%s' Fid = (%d,%d,%d,%d) Short = '%s' Type %s DV %I64d", + StringCbPrintfA(buffer, sizeof(buffer), "'%S' Fid = (%d,%d,%d,%d) Short = '%S' Type %s DV %I64d", entryp->name, entryp->fid.cell, entryp->fid.volume, entryp->fid.vnode, entryp->fid.unique, entryp->shortName, diff --git a/src/WINNT/afsd/cm_btree.h b/src/WINNT/afsd/cm_btree.h index 3e37191..e19b1da 100644 --- a/src/WINNT/afsd/cm_btree.h +++ b/src/WINNT/afsd/cm_btree.h @@ -48,14 +48,18 @@ typedef struct node *Nptr; typedef struct key { - char *name; + normchar_t *name; /* Normalized name */ } keyT; - typedef struct dirdata { cm_fid_t fid; - char * longname; - char * origname; + int shortform; /* This is the short form entry. If + this value is non-zero, then there + is another entry in the B-Plus tree + corresponding to the long name of + this fid. */ + clientchar_t *cname; /* Client name (long) */ + fschar_t * fsname; /* FileServer name */ } dataT; typedef struct entry { @@ -138,20 +142,20 @@ Nptr lookup(Tree *B, keyT key); /******************* cache manager directory operations ***************/ -int cm_BPlusDirLookup(cm_dirOp_t * op, char *entry, cm_fid_t * cfid); -int cm_BPlusDirLookupOriginalName(cm_dirOp_t * op, char * entry, char ** originalNameRetp); -long cm_BPlusDirCreateEntry(cm_dirOp_t * op, char *entry, cm_fid_t * cfid); -int cm_BPlusDirDeleteEntry(cm_dirOp_t * op, char *entry); +int cm_BPlusCompareNormalizedKeys(keyT key1, keyT key2, int flags); +int cm_BPlusDirLookup(cm_dirOp_t * op, clientchar_t *entry, cm_fid_t * cfid); +int cm_BPlusDirLookupOriginalName(cm_dirOp_t * op, clientchar_t *entry, fschar_t **originalNameRetp); +long cm_BPlusDirCreateEntry(cm_dirOp_t * op, clientchar_t *entry, cm_fid_t * cfid); +int cm_BPlusDirDeleteEntry(cm_dirOp_t * op, clientchar_t *entry); long cm_BPlusDirBuildTree(cm_scache_t *scp, cm_user_t *userp, cm_req_t* reqp); void cm_BPlusDumpStats(void); -int cm_MemDumpBPlusStats(FILE *outputFile, char *cookie, int lock); - +int cm_MemDumpBPlusStats(FILE *outputFile, char *cookie, int lock); /******************* directory enumeration operations ****************/ typedef struct cm_direnum_entry { - char * name; - cm_fid_t fid; - char shortName[13]; + clientchar_t *name; + cm_fid_t fid; + normchar_t shortName[13]; } cm_direnum_entry_t; typedef struct cm_direnum { @@ -160,7 +164,7 @@ typedef struct cm_direnum { cm_direnum_entry_t entry[1]; } cm_direnum_t; -long cm_BPlusDirEnumerate(cm_scache_t *scp, afs_uint32 locked, char *maskp, cm_direnum_t **enumpp); +long cm_BPlusDirEnumerate(cm_scache_t *scp, afs_uint32 locked, clientchar_t *maskp, cm_direnum_t **enumpp); long cm_BPlusDirNextEnumEntry(cm_direnum_t *enump, cm_direnum_entry_t **entrypp); long cm_BPlusDirFreeEnumeration(cm_direnum_t *enump); long cm_BPlusDirEnumTest(cm_scache_t * dscp, afs_uint32 locked); @@ -182,7 +186,7 @@ extern afs_uint64 bplus_free_time; /* access keys and pointers in a node */ #define getkey(j, q) (nAdr(j).e[(q)].key) #define getnode(j, q) (nAdr(j).e[(q)].downNode) -#define setkey(j, q, v) ((q > 0) ? nAdr(j).e[(q)].key.name = strdup((v).name) : NULL) +#define setkey(j, q, v) ((q > 0) ? nAdr(j).e[(q)].key.name = cm_NormStrDup((v).name) : NULL) #define setnode(j, q, v) (nAdr(j).e[(q)].downNode = (v)) /* access tree flag values */ diff --git a/src/WINNT/afsd/cm_buf.h b/src/WINNT/afsd/cm_buf.h index 683b152..09d49ed 100644 --- a/src/WINNT/afsd/cm_buf.h +++ b/src/WINNT/afsd/cm_buf.h @@ -203,6 +203,8 @@ extern long buf_CleanDirtyBuffers(cm_scache_t *scp); extern long buf_ForceDataVersion(cm_scache_t * scp, afs_uint64 fromVersion, afs_uint64 toVersion); +extern int cm_DumpBufHashTable(FILE *outputFile, char *cookie, int lock); + /* error codes */ #define CM_BUF_EXISTS 1 /* buffer exists, and shouldn't */ #endif /* _BUF_H__ENV_ */ diff --git a/src/WINNT/afsd/cm_callback.c b/src/WINNT/afsd/cm_callback.c index 1649423..ffa1306 100644 --- a/src/WINNT/afsd/cm_callback.c +++ b/src/WINNT/afsd/cm_callback.c @@ -18,6 +18,7 @@ #include #include "afsd.h" +#include "smb.h" #include #include @@ -744,8 +745,10 @@ SRXAFSCB_GetCE(struct rx_call *callp, long index, AFSDBCacheEntry *cep) cep->cbExpires = volp->cbExpiresRO; cm_PutVolume(volp); } - } else - cep->cbExpires = scp->cbExpires; + } else { + /* TODO: deal with time_t below */ + cep->cbExpires = (afs_int32) scp->cbExpires; + } cep->refCount = scp->refCount; cep->opens = scp->openReads; cep->writers = scp->openWrites; @@ -859,8 +862,10 @@ SRXAFSCB_GetCE64(struct rx_call *callp, long index, AFSDBCacheEntry64 *cep) cep->cbExpires = volp->cbExpiresRO; cm_PutVolume(volp); } - } else - cep->cbExpires = scp->cbExpires; + } else { + /* TODO: handle time_t */ + cep->cbExpires = (afs_int32) scp->cbExpires; + } cep->refCount = scp->refCount; cep->opens = scp->openReads; cep->writers = scp->openWrites; @@ -1313,8 +1318,7 @@ int SRXAFSCB_GetLocalCell(struct rx_call *callp, char **a_name) ntohl(host), ntohs(port)); if (cm_data.rootCellp) { - t_name = (char *)malloc(strlen(cm_data.rootCellp->name)+1); - strcpy(t_name, cm_data.rootCellp->name); + t_name = strdup(cm_data.rootCellp->name); } else { t_name = (char *)malloc(1); t_name[0] = '\0'; diff --git a/src/WINNT/afsd/cm_conn.h b/src/WINNT/afsd/cm_conn.h index 6220592..30121f3 100644 --- a/src/WINNT/afsd/cm_conn.h +++ b/src/WINNT/afsd/cm_conn.h @@ -39,16 +39,16 @@ typedef struct cm_conn { * to the cache manager functions. */ typedef struct cm_req { - DWORD startTime; /* Quit before RDR times us out */ - int rpcError; /* RPC error code */ - int volumeError; /* volume error code */ - int accessError; /* access error code */ - struct cm_server * tokenIdleErrorServp; /* server that reported a token/idle error other than expired */ - int tokenError; - int idleError; - afs_uint32 flags; - char * tidPathp; - char * relPathp; + DWORD startTime; /* Quit before RDR times us out */ + int rpcError; /* RPC error code */ + int volumeError; /* volume error code */ + int accessError; /* access error code */ + struct cm_server * tokenIdleErrorServp; /* server that reported a token/idle error other than expired */ + int tokenError; + int idleError; + afs_uint32 flags; + clientchar_t * tidPathp; + clientchar_t * relPathp; } cm_req_t; /* flags in cm_req structure */ diff --git a/src/WINNT/afsd/cm_dnlc.c b/src/WINNT/afsd/cm_dnlc.c index 7cb8afc..bcecf59 100644 --- a/src/WINNT/afsd/cm_dnlc.c +++ b/src/WINNT/afsd/cm_dnlc.c @@ -105,27 +105,27 @@ InsertEntry(cm_nc_t *tnc) void cm_dnlcEnter ( cm_scache_t *adp, - char *aname, + normchar_t *nname, cm_scache_t *avc ) { cm_nc_t *tnc; unsigned int key, skey, new=0; - char *ts = aname; + normchar_t *ts = nname; int safety; int writeLocked = 0; if (!cm_useDnlc) return ; - if (!strcmp(aname,".") || !strcmp(aname,"..")) + if (!cm_NormStrCmp(nname,_C(".")) || !cm_NormStrCmp(nname,_C(".."))) return ; if ( cm_debugDnlc ) - osi_Log3(afsd_logp,"cm_dnlcEnter dir %x name %s scache %x", - adp, osi_LogSaveString(afsd_logp,aname), avc); + osi_Log3(afsd_logp,"cm_dnlcEnter dir %x name %S scache %x", + adp, osi_LogSaveStringW(afsd_logp,nname), avc); dnlcHash( ts, key ); /* leaves ts pointing at the NULL */ - if (ts - aname >= CM_AFSNCNAMESIZE) + if (ts - nname >= CM_AFSNCNAMESIZE) return ; skey = key & (NHSIZE -1); @@ -133,7 +133,7 @@ cm_dnlcEnter ( cm_scache_t *adp, lock_ObtainRead(&cm_dnlcLock); retry: for (tnc = cm_data.nameHash[skey], safety=0; tnc; tnc = tnc->next, safety++ ) - if ((tnc->dirp == adp) && (!strcmp(tnc->name, aname))) + if ((tnc->dirp == adp) && (!cm_NormStrCmp(tnc->name, nname))) break; /* preexisting entry */ else if ( tnc->next == cm_data.nameHash[skey]) /* end of list */ { @@ -169,10 +169,10 @@ cm_dnlcEnter ( cm_scache_t *adp, tnc->dirp = adp; tnc->vp = avc; tnc->key = key; - memcpy (tnc->name, aname, ts-aname+1); /* include the NULL */ + memcpy (tnc->name, nname, (ts-nname+1)*sizeof(normchar_t)); /* include the NULL */ if ( new ) /* insert entry only if it is newly created */ - InsertEntry(tnc); + InsertEntry(tnc); } if (writeLocked) @@ -192,8 +192,8 @@ cm_dnlcLookup (cm_scache_t *adp, cm_lookupSearch_t* sp) { cm_scache_t * tvc; unsigned int key, skey; - char* aname = sp->searchNamep; - char *ts = aname; + normchar_t* nname = sp->nsearchNamep; + normchar_t *ts = nname; cm_nc_t * tnc, * tnc_begin; int safety, match; @@ -201,12 +201,12 @@ cm_dnlcLookup (cm_scache_t *adp, cm_lookupSearch_t* sp) return NULL; if ( cm_debugDnlc ) - osi_Log2(afsd_logp, "cm_dnlcLookup dir %x name %s", - adp, osi_LogSaveString(afsd_logp,aname)); + osi_Log2(afsd_logp, "cm_dnlcLookup dir %x name %S", + adp, osi_LogSaveStringW(afsd_logp,nname)); dnlcHash( ts, key ); /* leaves ts pointing at the NULL */ - if (ts - aname >= CM_AFSNCNAMESIZE) { + if (ts - nname >= CM_AFSNCNAMESIZE) { InterlockedIncrement(&dnlcstats.lookups); InterlockedIncrement(&dnlcstats.misses); return NULL; @@ -225,26 +225,26 @@ cm_dnlcLookup (cm_scache_t *adp, cm_lookupSearch_t* sp) if (tnc->dirp == adp) { if( cm_debugDnlc ) - osi_Log1(afsd_logp,"Looking at [%s]", - osi_LogSaveString(afsd_logp,tnc->name)); + osi_Log1(afsd_logp,"Looking at [%S]", + osi_LogSaveStringW(afsd_logp,tnc->name)); if ( sp->caseFold ) /* case insensitive */ { - match = cm_stricmp_utf8(tnc->name, aname); + match = cm_NormStrCmpI(tnc->name, nname); if ( !match ) /* something matches */ { tvc = tnc->vp; ts = tnc->name; /* determine what type of match it is */ - if ( !strcmp(tnc->name, aname)) + if ( !cm_NormStrCmp(tnc->name, nname)) { /* exact match. */ sp->ExactFound = 1; if( cm_debugDnlc ) - osi_Log1(afsd_logp,"DNLC found exact match [%s]", - osi_LogSaveString(afsd_logp,tnc->name)); + osi_Log1(afsd_logp,"DNLC found exact match [%S]", + osi_LogSaveStringW(afsd_logp,tnc->name)); break; } else if ( cm_NoneUpper(tnc->name)) @@ -258,7 +258,7 @@ cm_dnlcLookup (cm_scache_t *adp, cm_lookupSearch_t* sp) } else /* case sensitive */ { - match = strcmp(tnc->name, aname); + match = cm_NormStrCmp(tnc->name, nname); if ( !match ) /* found a match */ { sp->ExactFound = 1; @@ -285,9 +285,9 @@ cm_dnlcLookup (cm_scache_t *adp, cm_lookupSearch_t* sp) } if(cm_debugDnlc && ts) { - osi_Log3(afsd_logp, "DNLC matched [%s] for [%s] with vnode[%ld]", - osi_LogSaveString(afsd_logp,ts), - osi_LogSaveString(afsd_logp,aname), + osi_Log3(afsd_logp, "DNLC matched [%S] for [%W] with vnode[%ld]", + osi_LogSaveStringW(afsd_logp,ts), + osi_LogSaveStringW(afsd_logp,nname), (long) tvc->fid.vnode); } @@ -337,22 +337,22 @@ RemoveEntry (cm_nc_t *tnc, unsigned int key) void -cm_dnlcRemove (cm_scache_t *adp, char *aname) +cm_dnlcRemove (cm_scache_t *adp, normchar_t *nname) { unsigned int key, skey, error=0; int found= 0, safety; - char *ts = aname; + normchar_t *ts = nname; cm_nc_t *tnc, *tmp; if (!cm_useDnlc) return ; if ( cm_debugDnlc ) - osi_Log2(afsd_logp, "cm_dnlcRemove dir %x name %s", - adp, osi_LogSaveString(afsd_logp,aname)); + osi_Log2(afsd_logp, "cm_dnlcRemove dir %x name %S", + adp, osi_LogSaveStringW(afsd_logp,nname)); dnlcHash( ts, key ); /* leaves ts pointing at the NULL */ - if (ts - aname >= CM_AFSNCNAMESIZE) + if (ts - nname >= CM_AFSNCNAMESIZE) return ; skey = key & (NHSIZE -1); @@ -362,7 +362,7 @@ cm_dnlcRemove (cm_scache_t *adp, char *aname) for (tnc = cm_data.nameHash[skey], safety=0; tnc; safety++) { if ( (tnc->dirp == adp) && (tnc->key == key) - && !strcmp(tnc->name,aname) ) + && !cm_NormStrCmp(tnc->name,nname) ) { tmp = tnc->next; error = RemoveEntry(tnc, skey); diff --git a/src/WINNT/afsd/cm_dnlc.h b/src/WINNT/afsd/cm_dnlc.h index c1c0ba3..d8a8890 100644 --- a/src/WINNT/afsd/cm_dnlc.h +++ b/src/WINNT/afsd/cm_dnlc.h @@ -20,7 +20,7 @@ typedef struct nc { unsigned int key; struct nc *next, *prev; cm_scache_t *dirp, *vp; - unsigned char name[CM_AFSNCNAMESIZE]; + normchar_t name[CM_AFSNCNAMESIZE]; } cm_nc_t; typedef struct { @@ -29,12 +29,12 @@ typedef struct { afs_int32 cycles, lookuprace; } cm_dnlcstats_t; -#define dnlcHash(ts, hval) for (hval=0; *ts; ts++) { \ - hval *= 173; \ - hval += cm_foldUpper[(unsigned char)(*ts)]; \ - } -extern void cm_dnlcEnter(cm_scache_t *adp, char *name, cm_scache_t *avc); -extern void cm_dnlcRemove(cm_scache_t *adp, char *name); +#define dnlcHash(ts, hval) for (hval=0; *ts; ts++) { \ + hval *= 173; \ + hval += cm_NormCharUpr(*ts); \ + } +extern void cm_dnlcEnter(cm_scache_t *adp, normchar_t *name, cm_scache_t *avc); +extern void cm_dnlcRemove(cm_scache_t *adp, normchar_t *name); extern void cm_dnlcPurgedp(cm_scache_t *adp); extern void cm_dnlcPurgevp(cm_scache_t *avc); extern void cm_dnlcPurge(void); diff --git a/src/WINNT/afsd/cm_dns.c b/src/WINNT/afsd/cm_dns.c index 2cd822f..ee92c6e 100644 --- a/src/WINNT/afsd/cm_dns.c +++ b/src/WINNT/afsd/cm_dns.c @@ -14,8 +14,8 @@ #include #include #include "cm_dns_private.h" -#include "cm_dns.h" #include "cm_nls.h" +#include "cm_dns.h" #include #include #if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0500) @@ -23,6 +23,7 @@ #define DNSAPI_ENV #endif #include +#include /*extern void afsi_log(char *pattern, ...);*/ @@ -31,51 +32,56 @@ static int cm_dnsEnabled = -1; void DNSlowerCase(char *str) { - int i; + unsigned int i; - for (i=0; i= 'A' && str[i] <= 'Z') - str[i] += 'a' - 'A'; + for (i=0; i= 'A' && str[i] <= 'Z') + str[i] += 'a' - 'A'; } int cm_InitDNS(int enabled) { #ifndef DNSAPI_ENV - char configpath[100]; - int len; - int code; - char *addr; - - if (!enabled) { fprintf(stderr, "DNS support disabled\n"); cm_dnsEnabled = 0; return 0; } - - /* First try AFS_NS environment var. */ - addr = getenv("AFS_NS"); - if (addr && inet_addr(addr) != -1) { - strcpy(dns_addr, addr); - } else { - /* Now check for the AFSDNS.INI file */ - code = GetWindowsDirectory(configpath, sizeof(configpath)); - if (code == 0 || code > sizeof(configpath)) return -1; - strcat(configpath, "\\afsdns.ini"); - - /* Currently we only get (and query) the first nameserver. Getting - list of mult. nameservers should be easy to do. */ - len = GetPrivateProfileString("AFS Domain Name Servers", "ns1", NULL, - dns_addr, sizeof(dns_addr), - configpath); - - if (len == 0 || inet_addr(dns_addr) == -1) { - fprintf(stderr, "No valid name server addresses found, DNS lookup is " - "disabled\n"); - cm_dnsEnabled = 0; /* failed */ - return -1; /* No name servers defined */ + char configpath[100]; + int len; + int code; + char *addr; + + if (!enabled) { + fprintf(stderr, "DNS support disabled\n"); + cm_dnsEnabled = 0; + return 0; + } + + /* First try AFS_NS environment var. */ + addr = getenv("AFS_NS"); + if (addr && inet_addr(addr) != -1) { + strcpy(dns_addr, addr); + } else { + /* Now check for the AFSDNS.INI file */ + code = GetWindowsDirectory(configpath, sizeof(configpath)); + if (code == 0 || code > sizeof(configpath)) return -1; + strcat(configpath, "\\afsdns.ini"); + + /* Currently we only get (and query) the first nameserver. Getting + list of mult. nameservers should be easy to do. */ + len = GetPrivateProfileString("AFS Domain Name Servers", "ns1", NULL, + dns_addr, sizeof(dns_addr), + configpath); + + if (len == 0 || inet_addr(dns_addr) == -1) { + fprintf(stderr, "No valid name server addresses found, DNS lookup is " + "disabled\n"); + cm_dnsEnabled = 0; /* failed */ + return -1; /* No name servers defined */ + } + else + fprintf(stderr, "Found DNS server %s\n", dns_addr); } - else fprintf(stderr, "Found DNS server %s\n", dns_addr); - } #endif /* DNSAPI_ENV */ - cm_dnsEnabled = 1; - return 0; + cm_dnsEnabled = 1; + return 0; } #ifndef DNSAPI_ENV @@ -618,72 +624,67 @@ int getAFSServer(char *cellName, int *cellHostAddrs, char cellHostNames[][MAXHOS int *numServers, int *ttl) { #ifndef DNSAPI_ENV - /*static AFS_SRV_LIST srvList; - static int ans = 0;*/ - SOCKET commSock; - SOCKADDR_IN sockAddr; - PDNS_HDR pDNShdr; - char buffer[BUFSIZE]; - char query[1024]; - int rc; + SOCKET commSock; + SOCKADDR_IN sockAddr; + PDNS_HDR pDNShdr; + char buffer[BUFSIZE]; + char query[1024]; + int rc; #ifdef DEBUG - fprintf(stderr, "getAFSServer: cell %s, cm_dnsEnabled=%d\n", cellName, cm_dnsEnabled); + fprintf(stderr, "getAFSServer: cell %s, cm_dnsEnabled=%d\n", cellName, cm_dnsEnabled); #endif #if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0500) - if (cm_dnsEnabled == -1) { /* not yet initialized, eg when called by klog */ - cm_InitDNS(1); /* assume enabled */ - } + if (cm_dnsEnabled == -1) { /* not yet initialized, eg when called by klog */ + cm_InitDNS(1); /* assume enabled */ + } #endif - if (cm_dnsEnabled == 0) { /* possibly we failed in cm_InitDNS above */ - fprintf(stderr, "DNS initialization failed, disabled\n"); - *numServers = 0; - return -1; - } + if (cm_dnsEnabled == 0) { /* possibly we failed in cm_InitDNS above */ + fprintf(stderr, "DNS initialization failed, disabled\n"); + *numServers = 0; + return -1; + } - sockAddr = setSockAddr(dns_addr, DNS_PORT); + sockAddr = setSockAddr(dns_addr, DNS_PORT); - commSock = socket( AF_INET, SOCK_DGRAM, 0 ); - if ( commSock < 0 ) + commSock = socket( AF_INET, SOCK_DGRAM, 0 ); + if ( commSock < 0 ) { - /*afsi_log("socket() failed\n");*/ - fprintf(stderr, "getAFSServer: socket() failed, errno=%d\n", errno); - *numServers = 0; - return (-1); + /*afsi_log("socket() failed\n");*/ + fprintf(stderr, "getAFSServer: socket() failed, errno=%d\n", errno); + *numServers = 0; + return (-1); } - - strncpy(query, cellName, 1024); - query[1023] = 0; - if (query[strlen(query)-1] != '.') { - strncat(query,".",1024); - query[1023] = 0; - } - rc = send_DNS_AFSDB_Query(cellName,commSock,sockAddr, buffer); - if (rc < 0) { - fprintf(stderr,"getAFSServer: send_DNS_AFSDB_Query failed\n"); - *numServers = 0; - return -1; - } + StringCbCopyA(query, sizeof(query), cellName); + if (query[strlen(query)-1] != '.') { + StringCbCatA(query, sizeof(query), "."); + } + + rc = send_DNS_AFSDB_Query(cellName,commSock,sockAddr, buffer); + if (rc < 0) { + fprintf(stderr,"getAFSServer: send_DNS_AFSDB_Query failed\n"); + *numServers = 0; + return -1; + } - pDNShdr = get_DNS_Response(commSock,sockAddr, buffer); - - /*printReplyBuffer_AFSDB(pDNShdr);*/ - if (pDNShdr) - processReplyBuffer_AFSDB(commSock, pDNShdr, cellHostAddrs, cellHostNames, numServers, ttl); - else - *numServers = 0; + pDNShdr = get_DNS_Response(commSock,sockAddr, buffer); - closesocket(commSock); - if (*numServers == 0) - return(-1); + /*printReplyBuffer_AFSDB(pDNShdr);*/ + if (pDNShdr) + processReplyBuffer_AFSDB(commSock, pDNShdr, cellHostAddrs, cellHostNames, numServers, ttl); + else + *numServers = 0; - else - return 0; + closesocket(commSock); + if (*numServers == 0) + return(-1); + else + return 0; #else /* DNSAPI_ENV */ PDNS_RECORD pDnsCell, pDnsIter, pDnsVol,pDnsVolIter, pDnsCIter; - DWORD i; + int i; struct sockaddr_in vlSockAddr; char query[1024]; @@ -696,22 +697,20 @@ int getAFSServer(char *cellName, int *cellHostAddrs, char cellHostNames[][MAXHOS *ttl = 0; /* query the AFSDB records of cell */ - strncpy(query, cellName, 1024); - query[1023] = 0; + StringCbCopyA(query, sizeof(query), cellName); if (query[strlen(query)-1] != '.') { - strncat(query,".",1024); - query[1023] = 0; + StringCbCatA(query, sizeof(query), "."); } if (DnsQuery_A(query, DNS_TYPE_AFSDB, DNS_QUERY_STANDARD, NULL, &pDnsCell, NULL) == ERROR_SUCCESS) { memset((void*) &vlSockAddr, 0, sizeof(vlSockAddr)); - + /* go through the returned records */ for (pDnsIter = pDnsCell;pDnsIter; pDnsIter = pDnsIter->pNext) { /* if we find an AFSDB record with Preference set to 1, we found a volserver */ if (pDnsIter->wType == DNS_TYPE_AFSDB && pDnsIter->Data.Afsdb.wPreference == 1) { - strncpy(cellHostNames[*numServers], pDnsIter->Data.Afsdb.pNameExchange, MAXHOSTCHARS); - cellHostNames[*numServers][MAXHOSTCHARS-1]='\0'; + StringCbCopyA(cellHostNames[*numServers], sizeof(cellHostNames[*numServers]), + pDnsIter->Data.Afsdb.pNameExchange); (*numServers)++; if (!*ttl) @@ -731,7 +730,7 @@ int getAFSServer(char *cellName, int *cellHostAddrs, char cellHostNames[][MAXHOS for (i=0;i<*numServers;i++) if(cm_stricmp_utf8(pDnsIter->pName, cellHostNames[i]) == 0) cellHostAddrs[i] = pDnsIter->Data.A.IpAddress; - } + } for (i=0;i<*numServers;i++) { /* if we don't have an IP yet, then we should try resolving the volserver hostname @@ -771,4 +770,100 @@ int getAFSServer(char *cellName, int *cellHostAddrs, char cellHostNames[][MAXHOS return -1; #endif /* DNSAPI_ENV */ } + +int getAFSServerW(cm_unichar_t *cellName, int *cellHostAddrs, + cm_unichar_t cellHostNames[][MAXHOSTCHARS], + int *numServers, int *ttl) +{ +#ifdef DNSAPI_ENV + PDNS_RECORDW pDnsCell, pDnsIter, pDnsVol,pDnsVolIter, pDnsCIter; + int i; + struct sockaddr_in vlSockAddr; + cm_unichar_t query[1024]; + +#ifdef AFS_FREELANCE_CLIENT + if ( cm_stricmp_utf16(cellName, L"Freelance.Local.Root") == 0 ) + return -1; +#endif /* AFS_FREELANCE_CLIENT */ + + *numServers = 0; + *ttl = 0; + + /* query the AFSDB records of cell */ + StringCbCopyW(query, sizeof(query), cellName); + if (query[wcslen(query)-1] != L'.') { + StringCbCatW(query, sizeof(query), L"."); + } + + if (DnsQuery_W(query, DNS_TYPE_AFSDB, DNS_QUERY_STANDARD, NULL, (PDNS_RECORD *) &pDnsCell, + NULL) == ERROR_SUCCESS) { + memset((void*) &vlSockAddr, 0, sizeof(vlSockAddr)); + + /* go through the returned records */ + for (pDnsIter = pDnsCell;pDnsIter; pDnsIter = pDnsIter->pNext) { + /* if we find an AFSDB record with Preference set to 1, we found a volserver */ + if (pDnsIter->wType == DNS_TYPE_AFSDB && pDnsIter->Data.Afsdb.wPreference == 1) { + StringCbCopyW(cellHostNames[*numServers], sizeof(cellHostNames[*numServers]), + pDnsIter->Data.Afsdb.pNameExchange); + (*numServers)++; + + if (!*ttl) + *ttl = pDnsIter->dwTtl; + if (*numServers == AFSMAXCELLHOSTS) + break; + } + } + + for (i=0;i<*numServers;i++) + cellHostAddrs[i] = 0; + + /* now check if there are any A records in the results */ + for (pDnsIter = pDnsCell; pDnsIter; pDnsIter = pDnsIter->pNext) { + if(pDnsIter->wType == DNS_TYPE_A) + /* check if its for one of the volservers */ + for (i=0;i<*numServers;i++) + if(cm_stricmp_utf16(pDnsIter->pName, cellHostNames[i]) == 0) + cellHostAddrs[i] = pDnsIter->Data.A.IpAddress; + } + + for (i=0;i<*numServers;i++) { + /* if we don't have an IP yet, then we should try resolving the volserver hostname + in a separate query. */ + if (!cellHostAddrs[i]) { + if (DnsQuery_W(cellHostNames[i], DNS_TYPE_A, DNS_QUERY_STANDARD, NULL, + (PDNS_RECORD *) &pDnsVol, NULL) == ERROR_SUCCESS) { + for (pDnsVolIter = pDnsVol; pDnsVolIter; pDnsVolIter=pDnsVolIter->pNext) { + /* if we get an A record, keep it */ + if (pDnsVolIter->wType == DNS_TYPE_A && cm_stricmp_utf16(cellHostNames[i], pDnsVolIter->pName)==0) { + cellHostAddrs[i] = pDnsVolIter->Data.A.IpAddress; + break; + } + /* if we get a CNAME, look for a corresponding A record */ + if (pDnsVolIter->wType == DNS_TYPE_CNAME && cm_stricmp_utf16(cellHostNames[i], pDnsVolIter->pName)==0) { + for (pDnsCIter=pDnsVolIter; pDnsCIter; pDnsCIter=pDnsCIter->pNext) { + if (pDnsCIter->wType == DNS_TYPE_A && cm_stricmp_utf16(pDnsVolIter->Data.CNAME.pNameHost, pDnsCIter->pName)==0) { + cellHostAddrs[i] = pDnsCIter->Data.A.IpAddress; + break; + } + } + if (cellHostAddrs[i]) + break; + /* TODO: if the additional section is missing, then do another lookup for the CNAME */ + } + } + /* we are done with the volserver lookup */ + DnsRecordListFree((PDNS_RECORD) pDnsVol, DnsFreeRecordListDeep); + } + } + } + DnsRecordListFree((PDNS_RECORD) pDnsCell, DnsFreeRecordListDeep); + } + + if ( *numServers > 0 ) + return 0; + else +#endif /* DNSAPI_ENV */ + return -1; +} #endif /* AFS_AFSDB_ENV */ + diff --git a/src/WINNT/afsd/cm_dns.h b/src/WINNT/afsd/cm_dns.h index 6bfa381..ed41d9c 100644 --- a/src/WINNT/afsd/cm_dns.h +++ b/src/WINNT/afsd/cm_dns.h @@ -15,6 +15,12 @@ names for the given cell, ending in null */ int getAFSServer(char *cellname, int *cellHostAddrs, char cellHostNames[][MAXHOSTCHARS], int *numServers, int *ttl); +/* Same as above, but using cm_unichar_t. Note that this functon will + only be defined for DNSAPI_ENV. */ +int getAFSServerW(cm_unichar_t *cellName, int *cellHostAddrs, + cm_unichar_t cellHostNames[][MAXHOSTCHARS], + int *numServers, int *ttl); + /* a supplement for the DJGPP gethostbyname ... which never bothers calling a DNS server ... so this function takes care of that. This should be called when you diff --git a/src/WINNT/afsd/cm_ioctl.c b/src/WINNT/afsd/cm_ioctl.c index fcb20b0..3457bb1 100644 --- a/src/WINNT/afsd/cm_ioctl.c +++ b/src/WINNT/afsd/cm_ioctl.c @@ -54,6 +54,7 @@ osi_mutex_t cm_Afsdsbmt_Lock; extern afs_int32 cryptall; extern char cm_NetbiosName[]; +extern clientchar_t cm_NetbiosNameC[]; extern void afsi_log(char *pattern, ...); @@ -211,22 +212,86 @@ TranslateExtendedChars(char *str) if (!str || !*str) return; - CharToOem(str, str); + CharToOemA(str, str); } - -/* - * Utility function. - * If the IoctlPath is not parsed then it must be skipped. - */ -void -cm_SkipIoctlPath(cm_ioctl_t *ioctlp) +void cm_SkipIoctlPath(cm_ioctl_t *ioctlp) { size_t temp; - + temp = strlen(ioctlp->inDatap) + 1; ioctlp->inDatap += temp; -} +} + + +clientchar_t * cm_ParseIoctlStringAlloc(cm_ioctl_t *ioctlp, const char * ext_instrp) +{ + clientchar_t * rs = NULL; + const char * instrp; + + instrp = (ext_instrp)?ext_instrp:ioctlp->inDatap; + + if ((ioctlp->flags & CM_IOCTLFLAG_USEUTF8) == CM_IOCTLFLAG_USEUTF8) { + rs = cm_Utf8ToClientStringAlloc(instrp, -1, NULL); + } else { + int cch; + + /* Not a UTF-8 string */ + if (smb_StoreAnsiFilenames) { + cch = cm_AnsiToClientString(instrp, -1, NULL, 0); +#ifdef DEBUG + osi_assert(cch > 0); +#endif + rs = malloc(cch * sizeof(clientchar_t)); + cm_AnsiToClientString(instrp, -1, rs, cch); + } else { + cch = cm_OemToClientString(instrp, -1, NULL, 0); +#ifdef DEBUG + osi_assert(cch > 0); +#endif + rs = malloc(cch * sizeof(clientchar_t)); + cm_OemToClientString(instrp, -1, rs, cch); + } + } + + if (ext_instrp == NULL) { + ioctlp->inDatap += strlen(ioctlp->inDatap) + 1; + } + return rs; +} + +int cm_UnparseIoctlString(cm_ioctl_t *ioctlp, + char * ext_outp, + const clientchar_t * cstr, int cchlen) +{ + char *outp; + int cchout; + + outp = ((ext_outp == NULL)? ioctlp->outDatap : ext_outp); + + if ((ioctlp->flags & CM_IOCTLFLAG_USEUTF8) == CM_IOCTLFLAG_USEUTF8) { + cchout = cm_ClientStringToUtf8(cstr, cchlen, outp, + SMB_IOCTL_MAXDATA - (outp - ioctlp->outAllocp)); + } else { + if (smb_StoreAnsiFilenames) { + cchout = WideCharToMultiByte(CP_ACP, 0, cstr, cchlen, + outp, + SMB_IOCTL_MAXDATA - (outp - ioctlp->outAllocp), + NULL, NULL); + } else { + cchout = WideCharToMultiByte(CP_OEMCP, 0, cstr, cchlen, + outp, + SMB_IOCTL_MAXDATA - (outp - ioctlp->outAllocp), + NULL, NULL); + } + } + + if (cchout > 0 && ext_outp == NULL) { + ioctlp->outDatap += cchout; + } + + return cchout; +} /* * Must be called before XXX_ParseIoctlPath or cm_SkipIoctlPath @@ -267,34 +332,35 @@ cm_IoctlSkipQueryOptions(struct cm_ioctl *ioctlp, struct cm_user *userp) * the AFS path that should be written into afsdsbmt.ini). */ void -cm_NormalizeAfsPath(char *outpathp, long outlen, char *inpathp) +cm_NormalizeAfsPath(clientchar_t *outpathp, long cchlen, clientchar_t *inpathp) { - char *cp; - char bslash_mountRoot[256]; + clientchar_t *cp; + clientchar_t bslash_mountRoot[256]; - strncpy(bslash_mountRoot, cm_mountRoot, sizeof(bslash_mountRoot) - 1); + cm_ClientStrCpy(bslash_mountRoot, lengthof(bslash_mountRoot), cm_mountRootC); bslash_mountRoot[0] = '\\'; - - if (!strnicmp (inpathp, cm_mountRoot, strlen(cm_mountRoot))) - StringCbCopy(outpathp, outlen, inpathp); - else if (!strnicmp (inpathp, bslash_mountRoot, strlen(bslash_mountRoot))) - StringCbCopy(outpathp, outlen, inpathp); + + if (!cm_ClientStrCmpNI(inpathp, cm_mountRootC, cm_mountRootCLen)) + cm_ClientStrCpy(outpathp, cchlen, inpathp); + else if (!cm_ClientStrCmpNI(inpathp, bslash_mountRoot, + cm_ClientStrLen(bslash_mountRoot))) + cm_ClientStrCpy(outpathp, cchlen, inpathp); else if ((inpathp[0] == '/') || (inpathp[0] == '\\')) - StringCbPrintfA(outpathp, outlen, "%s%s", cm_mountRoot, inpathp); + cm_ClientStrPrintfN(outpathp, cchlen, _C("%s%s"), cm_mountRootC, inpathp); else // inpathp looks like "/usr" - StringCbPrintfA(outpathp, outlen, "%s/%s", cm_mountRoot, inpathp); + cm_ClientStrPrintfN(outpathp, cchlen, _C("%s/%s"), cm_mountRootC, inpathp); for (cp = outpathp; *cp != 0; ++cp) { if (*cp == '\\') *cp = '/'; - } + } - if (strlen(outpathp) && (outpathp[strlen(outpathp)-1] == '/')) { - outpathp[strlen(outpathp)-1] = 0; + if (cm_ClientStrLen(outpathp) && (outpathp[cm_ClientStrLen(outpathp)-1] == '/')) { + outpathp[cm_ClientStrLen(outpathp)-1] = 0; } - if (!strcmpi (outpathp, cm_mountRoot)) { - StringCbCopy(outpathp, outlen, cm_mountRoot); + if (!cm_ClientStrCmpI(outpathp, cm_mountRootC)) { + cm_ClientStrCpy(outpathp, cchlen, cm_mountRootC); } } @@ -379,11 +445,13 @@ cm_IoctlGetFileCellName(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scach { cellp = cm_FindCellByID(scp->fid.cell, CM_FLAG_NOPROBE); if (cellp) { - StringCbCopyA(ioctlp->outDatap, SMB_IOCTL_MAXDATA - (ioctlp->outDatap - ioctlp->outAllocp), cellp->name); - ioctlp->outDatap += strlen(ioctlp->outDatap) + 1; + clientchar_t * cellname; + + cellname = cm_FsStringToClientStringAlloc(cellp->name, -1, NULL); + cm_UnparseIoctlString(ioctlp, NULL, cellname, -1); + free(cellname); code = 0; - } - else + } else code = CM_ERROR_NOSUCHCELL; } @@ -539,10 +607,10 @@ cm_IoctlSetVolumeStatus(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scach AFSFetchVolumeStatus volStat; AFSStoreVolumeStatus storeStat; cm_volume_t *tvp; - char *cp; cm_cell_t *cellp; + char *cp; + clientchar_t *strp; struct rx_connection * callp; - int len; #ifdef AFS_FREELANCE_CLIENT if ( scp->fid.cell == AFS_FAKE_ROOT_CELL_ID && scp->fid.volume == AFS_FAKE_ROOT_VOL_ID ) { @@ -564,20 +632,23 @@ cm_IoctlSetVolumeStatus(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scach cm_PutVolume(tvp); /* Copy the junk out, using cp as a roving pointer. */ - cp = ioctlp->inDatap; - memcpy((char *)&volStat, cp, sizeof(AFSFetchVolumeStatus)); - cp += sizeof(AFSFetchVolumeStatus); + memcpy((char *)&volStat, ioctlp->inDatap, sizeof(AFSFetchVolumeStatus)); + ioctlp->inDatap += sizeof(AFSFetchVolumeStatus); + + strp = cm_ParseIoctlStringAlloc(ioctlp, NULL); + cm_ClientStringToFsString(strp, -1, volName, lengthof(volName)); + free(strp); - len = strlen(cp) + 1; - cm_NormalizeUtf8String(cp, len, volName, sizeof(volName)); - cp += len; + strp = cm_ParseIoctlStringAlloc(ioctlp, NULL); + cm_ClientStringToFsString(strp, -1, offLineMsg, lengthof(offLineMsg)); + free(strp); - len = strlen(cp) + 1; - cm_NormalizeUtf8String(cp, len, offLineMsg, sizeof(offLineMsg)); - cp += len; + strp = cm_ParseIoctlStringAlloc(ioctlp, NULL); + cm_ClientStringToFsString(strp, -1, motd, lengthof(motd)); + free(strp); + + strp = NULL; - len = strlen(cp) + 1; - cm_NormalizeUtf8String(cp, len, motd, sizeof(motd)); storeStat.Mask = 0; if (volStat.MinQuota != -1) { storeStat.MinQuota = volStat.MinQuota; @@ -595,7 +666,7 @@ cm_IoctlSetVolumeStatus(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scach callp = cm_GetRxConn(tcp); code = RXAFS_SetVolumeStatus(callp, scp->fid.volume, - &storeStat, volName, offLineMsg, motd); + &storeStat, volName, offLineMsg, motd); rx_PutConnection(callp); } while (cm_Analyze(tcp, userp, reqp, &scp->fid, NULL, NULL, NULL, code)); @@ -882,13 +953,12 @@ cm_IoctlStatMountPoint(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scache { afs_int32 code; cm_scache_t *scp; - char *cp; - - cp = ioctlp->inDatap; + clientchar_t *cp; + cp = cm_ParseIoctlStringAlloc(ioctlp, NULL); code = cm_Lookup(dscp, cp, CM_FLAG_NOMOUNTCHASE, userp, reqp, &scp); if (code) - return code; + goto done_2; lock_ObtainWrite(&scp->rw); code = cm_SyncOp(scp, NULL, userp, reqp, 0, @@ -906,16 +976,21 @@ cm_IoctlStatMountPoint(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scache code = cm_ReadMountPoint(scp, userp, reqp); if (code == 0) { - cp = ioctlp->outDatap; - StringCbCopyA(cp, SMB_IOCTL_MAXDATA - (cp - ioctlp->outAllocp), scp->mountPointStringp); - cp += strlen(cp) + 1; - ioctlp->outDatap = cp; + char * strp; + strp = ioctlp->outDatap; + StringCbCopyA(strp, SMB_IOCTL_MAXDATA - (strp - ioctlp->outAllocp), scp->mountPointStringp); + strp += strlen(strp) + 1; + ioctlp->outDatap = strp; } done: lock_ReleaseWrite(&scp->rw); cm_ReleaseSCache(scp); + done_2: + if (cp) + free(cp); + return code; } @@ -930,11 +1005,11 @@ cm_IoctlDeleteMountPoint(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scac { afs_int32 code; cm_scache_t *scp; - char *cp; - char *originalName = NULL; + clientchar_t *cp = NULL; + fschar_t *originalName = NULL; cm_dirOp_t dirop; - cp = ioctlp->inDatap; + cp = cm_ParseIoctlStringAlloc(ioctlp, NULL); code = cm_Lookup(dscp, cp, CM_FLAG_NOMOUNTCHASE, userp, reqp, &scp); @@ -944,7 +1019,7 @@ cm_IoctlDeleteMountPoint(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scac lock_ObtainWrite(&scp->rw); code = cm_SyncOp(scp, NULL, userp, reqp, 0, - CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); + CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); if (code) goto done2; @@ -973,15 +1048,15 @@ cm_IoctlDeleteMountPoint(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scac the file server. */ if (originalName == NULL) { - originalName = cp; + originalName = cm_ClientStringToFsStringAlloc(cp, -1, NULL); } /* cp is a normalized name. originalName is the actual name we saw on the fileserver. */ #ifdef AFS_FREELANCE_CLIENT if (cm_freelanceEnabled && dscp == cm_data.rootSCachep) { - /* we are adding the mount point to the root dir., so call - * the freelance code to do the add. */ + /* we are removing the mount point to the root dir., so call + * the freelance code to do the deletion. */ osi_Log0(afsd_logp,"IoctlDeleteMountPoint from Freelance root dir"); code = cm_FreelanceRemoveMount(originalName); } else @@ -992,13 +1067,8 @@ cm_IoctlDeleteMountPoint(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scac } if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH)) smb_NotifyChange(FILE_ACTION_REMOVED, - FILE_NOTIFY_CHANGE_DIR_NAME, - dscp, cp, NULL, TRUE); - - if (originalName != NULL && originalName != cp) { - free(originalName); - originalName = NULL; - } + FILE_NOTIFY_CHANGE_DIR_NAME, + dscp, cp, NULL, TRUE); lock_ObtainWrite(&scp->rw); done1: @@ -1010,6 +1080,12 @@ cm_IoctlDeleteMountPoint(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scac cm_ReleaseSCache(scp); done3: + if (originalName != NULL) + free(originalName); + + if (cp != NULL) + free(cp); + return code; } @@ -1055,7 +1131,7 @@ cm_IoctlCheckServers(struct cm_ioctl *ioctlp, struct cm_user *userp) ioctlp->inDatap = cp = ioctlp->inDatap + sizeof(long); if (cp - ioctlp->inAllocp < ioctlp->inCopied) /* still more data available */ haveCell = 1; - } + } /* * 1: fast check, don't contact servers. @@ -1067,18 +1143,18 @@ cm_IoctlCheckServers(struct cm_ioctl *ioctlp, struct cm_user *userp) if (!cellp) return CM_ERROR_NOSUCHCELL; } - else cellp = (cm_cell_t *) 0; + else + cellp = (cm_cell_t *) 0; if (!cellp && (temp & 2)) { /* use local cell */ - char wscell[CELL_MAXNAMELEN+1]; + fschar_t wscell[CELL_MAXNAMELEN+1]; cm_GetRootCellName(wscell); cellp = cm_GetCell(wscell, 0); } if (!(temp & 1)) { /* if not fast, call server checker routine */ /* check down servers */ - cm_CheckServers(CM_FLAG_CHECKDOWNSERVERS | CM_FLAG_CHECKUPSERVERS, - cellp); - } + cm_CheckServers(CM_FLAG_CHECKDOWNSERVERS | CM_FLAG_CHECKUPSERVERS, cellp); + } /* now return the current down server list */ cp = ioctlp->outDatap; @@ -1087,7 +1163,7 @@ cm_IoctlCheckServers(struct cm_ioctl *ioctlp, struct cm_user *userp) if (cellp && tsp->cellp != cellp) continue; /* cell spec'd and wrong */ if ((tsp->flags & CM_SERVERFLAG_DOWN) - && tsp->type == CM_SERVER_FILE) { + && tsp->type == CM_SERVER_FILE) { memcpy(cp, (char *)&tsp->addr.sin_addr.s_addr, sizeof(long)); cp += sizeof(long); } @@ -1246,6 +1322,7 @@ cm_IoctlGetCell(struct cm_ioctl *ioctlp, struct cm_user *userp) lock_ReleaseRead(&cm_cellLock); if (tcellp) { int max = 8; + clientchar_t * cellnamep; cp = ioctlp->outDatap; @@ -1264,10 +1341,11 @@ cm_IoctlGetCell(struct cm_ioctl *ioctlp, struct cm_user *userp) cp += sizeof(long); } lock_ReleaseRead(&cm_serverLock); - cp = basep + max * sizeof(afs_int32); - StringCbCopyA(cp, SMB_IOCTL_MAXDATA - (cp - ioctlp->outAllocp), tcellp->name); - cp += strlen(tcellp->name)+1; - ioctlp->outDatap = cp; + ioctlp->outDatap = basep + max * sizeof(afs_int32); + + cellnamep = cm_FsStringToClientStringAlloc(tcellp->name, -1, NULL); + cm_UnparseIoctlString(ioctlp, NULL, cellnamep, -1); + free(cellnamep); } if (tcellp) @@ -1352,9 +1430,10 @@ cm_IoctlGetWsCell(cm_ioctl_t *ioctlp, cm_user_t *userp) StringCbCopyA(ioctlp->outDatap, SMB_IOCTL_MAXDATA - (ioctlp->outDatap - ioctlp->outAllocp), "Freelance.Local.Root"); ioctlp->outDatap += strlen(ioctlp->outDatap) +1; } else if (cm_data.rootCellp) { + clientchar_t * cellnamep = cm_FsStringToClientStringAlloc(cm_data.rootCellp->name, -1, NULL); /* return the default cellname to the caller */ - StringCbCopyA(ioctlp->outDatap, SMB_IOCTL_MAXDATA - (ioctlp->outDatap - ioctlp->outAllocp), cm_data.rootCellp->name); - ioctlp->outDatap += strlen(ioctlp->outDatap) +1; + cm_UnparseIoctlString(ioctlp, NULL, cellnamep, -1); + free(cellnamep); } else { /* if we don't know our default cell, return failure */ code = CM_ERROR_NOSUCHCELL; @@ -1371,21 +1450,22 @@ cm_IoctlGetWsCell(cm_ioctl_t *ioctlp, cm_user_t *userp) afs_int32 cm_IoctlSysName(struct cm_ioctl *ioctlp, struct cm_user *userp) { - afs_uint32 setSysName, foundname = 0; - char *cp, *cp2, inname[MAXSYSNAME], outname[MAXSYSNAME]; - int t, count, num = 0; - char **sysnamelist[MAXSYSNAME]; - + afs_uint32 setSysName; + char *cp, *cp2; + clientchar_t *inname = NULL; + int t, count; + memcpy(&setSysName, ioctlp->inDatap, sizeof(afs_uint32)); ioctlp->inDatap += sizeof(afs_uint32); - + if (setSysName) { /* check my args */ if ( setSysName < 0 || setSysName > MAXNUMSYSNAMES ) return EINVAL; cp2 = ioctlp->inDatap; for ( cp=ioctlp->inDatap, count = 0; count < setSysName; count++ ) { - /* won't go past end of ioctlp->inDatap since maxsysname*num < ioctlp->inDatap length */ + /* won't go past end of ioctlp->inDatap since + maxsysname*num < ioctlp->inDatap length */ t = (int)strlen(cp); if (t >= MAXSYSNAME || t <= 0) return EINVAL; @@ -1398,64 +1478,59 @@ cm_IoctlSysName(struct cm_ioctl *ioctlp, struct cm_user *userp) /* inname gets first entry in case we're being a translator */ /* (we are never a translator) */ - t = (int)strlen(ioctlp->inDatap); - memcpy(inname, ioctlp->inDatap, t + 1); - ioctlp->inDatap += t + 1; - num = count; + inname = cm_ParseIoctlStringAlloc(ioctlp, NULL); } /* Not xlating, so local case */ if (!cm_sysName) osi_panic("cm_IoctlSysName: !cm_sysName\n", __FILE__, __LINE__); - if (!setSysName) { /* user just wants the info */ - StringCbCopyA(outname, sizeof(outname), cm_sysName); - foundname = cm_sysNameCount; - *sysnamelist = cm_sysNameList; - } else { + if (setSysName) { /* Local guy; only root can change sysname */ /* clear @sys entries from the dnlc, once afs_lookup can * do lookups of @sys entries and thinks it can trust them */ /* privs ok, store the entry, ... */ - StringCbCopyA(cm_sysName, sizeof(cm_sysName), inname); - StringCbCopyA(cm_sysNameList[0], MAXSYSNAME, inname); + + cm_ClientStrCpy(cm_sysName, lengthof(cm_sysName), inname); + cm_ClientStrCpy(cm_sysNameList[0], MAXSYSNAME, inname); + if (setSysName > 1) { /* ... or list */ - cp = ioctlp->inDatap; for (count = 1; count < setSysName; ++count) { + clientchar_t * newsysname; + if (!cm_sysNameList[count]) osi_panic("cm_IoctlSysName: no cm_sysNameList entry to write\n", - __FILE__, __LINE__); - t = (int)strlen(cp); - StringCbCopyA(cm_sysNameList[count], MAXSYSNAME, cp); - cp += t + 1; + __FILE__, __LINE__); + + newsysname = cm_ParseIoctlStringAlloc(ioctlp, NULL); + cm_ClientStrCpy(cm_sysNameList[count], MAXSYSNAME, newsysname); + free(newsysname); } } cm_sysNameCount = setSysName; - } + } else { + afs_int32 i32; - if (!setSysName) { /* return the sysname to the caller */ - cp = ioctlp->outDatap; - memcpy(cp, (char *)&foundname, sizeof(afs_int32)); - cp += sizeof(afs_int32); /* skip found flag */ - if (foundname) { - StringCbCopyA(cp, SMB_IOCTL_MAXDATA - (cp - ioctlp->outAllocp), outname); - cp += strlen(outname) + 1; /* skip name and terminating null char */ - for ( count=1; count < foundname ; ++count) { /* ... or list */ - if ( !(*sysnamelist)[count] ) + i32 = cm_sysNameCount; + memcpy(ioctlp->outDatap, &i32, sizeof(afs_int32)); + ioctlp->outDatap += sizeof(afs_int32); /* skip found flag */ + + if (cm_sysNameCount) { + for ( count=0; count < cm_sysNameCount ; ++count) { /* ... or list */ + if ( !cm_sysNameList[count] || *cm_sysNameList[count] == _C('\0')) osi_panic("cm_IoctlSysName: no cm_sysNameList entry to read\n", - __FILE__, __LINE__); - t = (int)strlen((*sysnamelist)[count]); - if (t >= MAXSYSNAME) - osi_panic("cm_IoctlSysName: sysname entry garbled\n", - __FILE__, __LINE__); - StringCbCopyA(cp, SMB_IOCTL_MAXDATA - (cp - ioctlp->outAllocp), (*sysnamelist)[count]); - cp += t + 1; + __FILE__, __LINE__); + cm_UnparseIoctlString(ioctlp, NULL, cm_sysNameList[count], -1); } } - ioctlp->outDatap = cp; } - + + if (inname) { + free(inname); + inname = NULL; + } + /* done: success */ return 0; } @@ -1470,8 +1545,15 @@ cm_IoctlGetCellStatus(struct cm_ioctl *ioctlp, struct cm_user *userp) { afs_uint32 temp; cm_cell_t *cellp; + clientchar_t * cellnamep; + fschar_t * fscellnamep; + + cellnamep = cm_ParseIoctlStringAlloc(ioctlp, NULL); + fscellnamep = cm_ClientStringToFsStringAlloc(cellnamep, -1, NULL); + cellp = cm_GetCell(fscellnamep, 0); + free(fscellnamep); + free(cellnamep); - cellp = cm_GetCell(ioctlp->inDatap, 0); if (!cellp) return CM_ERROR_NOSUCHCELL; @@ -1480,7 +1562,7 @@ cm_IoctlGetCellStatus(struct cm_ioctl *ioctlp, struct cm_user *userp) if (cellp->flags & CM_CELLFLAG_SUID) temp |= CM_SETCELLFLAG_SUID; lock_ReleaseMutex(&cellp->mx); - + /* now copy out parm */ memcpy(ioctlp->outDatap, &temp, sizeof(afs_uint32)); ioctlp->outDatap += sizeof(afs_uint32); @@ -1496,17 +1578,24 @@ cm_IoctlGetCellStatus(struct cm_ioctl *ioctlp, struct cm_user *userp) afs_int32 cm_IoctlSetCellStatus(struct cm_ioctl *ioctlp, struct cm_user *userp) { - afs_uint32 temp; + afs_uint32 flags; cm_cell_t *cellp; + clientchar_t *temp; + fschar_t * cellnamep; + + temp = cm_ParseIoctlStringAlloc(ioctlp, ioctlp->inDatap + 2*sizeof(afs_uint32)); + cellnamep = cm_ClientStringToFsStringAlloc(temp, -1, NULL); + cellp = cm_GetCell(cellnamep, 0); + free(temp); + free(cellnamep); - cellp = cm_GetCell(ioctlp->inDatap + 2*sizeof(afs_uint32), 0); if (!cellp) return CM_ERROR_NOSUCHCELL; - memcpy((char *)&temp, ioctlp->inDatap, sizeof(afs_uint32)); + memcpy((char *)&flags, ioctlp->inDatap, sizeof(afs_uint32)); lock_ObtainMutex(&cellp->mx); - if (temp & CM_SETCELLFLAG_SUID) + if (flags & CM_SETCELLFLAG_SUID) cellp->flags |= CM_CELLFLAG_SUID; else cellp->flags &= ~CM_CELLFLAG_SUID; @@ -1635,22 +1724,20 @@ cm_IoctlGetSPrefs(struct cm_ioctl *ioctlp, struct cm_user *userp) * dscp is held but not locked. */ afs_int32 -cm_IoctlCreateMountPoint(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scache_t *dscp, cm_req_t *reqp, char *leaf) +cm_IoctlCreateMountPoint(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scache_t *dscp, cm_req_t *reqp, clientchar_t *leaf) { afs_int32 code; cm_attr_t tattr; - char *cp; - char mpInfo[256]; - char fullCell[256]; - char volume[256]; - char cell[256]; + clientchar_t *cp; + fschar_t mpInfo[512]; /* mount point string */ + fschar_t fullCell[MAXCELLCHARS]; + fschar_t *fscell = NULL; + fschar_t *fsvolume = NULL; + clientchar_t volume[VL_MAXNAMELEN]; + clientchar_t *mpp = NULL; + clientchar_t *cell = NULL; int ttl; - /* Translate chars for the mount point name */ - if (!(ioctlp->flags & CM_IOCTLFLAG_USEUTF8)) { - TranslateExtendedChars(leaf); - } - /* * The fs command allows the user to specify partial cell names on NT. These must * be expanded to the full cell name for mount points so that the mount points will @@ -1658,37 +1745,46 @@ cm_IoctlCreateMountPoint(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scac */ /* Extract the possibly partial cell name */ - StringCbCopyA(cell, sizeof(cell), ioctlp->inDatap + 1); /* Skip the mp type character */ - - if (cp = strchr(cell, ':')) { + mpp = cm_ParseIoctlStringAlloc(ioctlp, NULL); + cell = cm_ClientCharNext(mpp); + if (cp = cm_ClientStrChr(cell, ':')) { + /* Extract the volume name */ *cp = 0; - StringCbCopyA(volume, sizeof(volume), cp + 1); - + cm_ClientStrCpy(volume, lengthof(volume), cm_ClientCharNext(cp)); + + fscell = cm_ClientStringToFsStringAlloc(cell, -1, NULL); + fsvolume = cm_ClientStringToFsStringAlloc(volume, -1, NULL); + /* Get the full name for this cell */ - code = cm_SearchCellFile(cell, fullCell, 0, 0); + code = cm_SearchCellFile(fscell, fullCell, 0, 0); #ifdef AFS_AFSDB_ENV if (code && cm_dnsEnabled) - code = cm_SearchCellByDNS(cell, fullCell, &ttl, 0, 0); + code = cm_SearchCellByDNS(fscell, fullCell, &ttl, 0, 0); #endif if (code) { - return CM_ERROR_NOSUCHCELL; + code = CM_ERROR_NOSUCHCELL; + goto done; } - - StringCbPrintfA(mpInfo, sizeof(mpInfo), "%c%s:%s", *ioctlp->inDatap, fullCell, volume); + + StringCbPrintfA(mpInfo, sizeof(mpInfo), "%c%s:%s", (char) *mpp, + fullCell, fsvolume); + } else { - /* No cell name specified */ - StringCbCopyA(mpInfo, sizeof(mpInfo), ioctlp->inDatap); + /* No cell name specified, so cell points at the volume instead. */ + fsvolume = cm_ClientStringToFsStringAlloc(cell, -1, NULL); + cm_ClientStringToFsString(mpp, -1, mpInfo, lengthof(mpInfo)); } #ifdef AFS_FREELANCE_CLIENT if (cm_freelanceEnabled && dscp == cm_data.rootSCachep) { - /* we are adding the mount point to the root dir., so call + /* we are adding the mount point to the root dir, so call * the freelance code to do the add. */ + fschar_t * fsleaf = cm_ClientStringToFsStringAlloc(leaf, -1, NULL); osi_Log0(afsd_logp,"IoctlCreateMountPoint within Freelance root dir"); - code = cm_FreelanceAddMount(leaf, fullCell, volume, - *ioctlp->inDatap == '%', NULL); - } else + code = cm_FreelanceAddMount(fsleaf, fullCell, fsvolume, *mpInfo == '%', NULL); + free(fsleaf); + } else #endif { /* create the symlink with mode 644. The lack of X bits tells @@ -1706,6 +1802,14 @@ cm_IoctlCreateMountPoint(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scac FILE_NOTIFY_CHANGE_DIR_NAME, dscp, leaf, NULL, TRUE); + done: + if (mpp) + free(mpp); + if (fscell) + free(fscell); + if (fsvolume) + free(fsvolume); + return code; } @@ -1716,7 +1820,7 @@ cm_IoctlCreateMountPoint(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scac * dscp is held but not locked. */ afs_int32 -cm_IoctlSymlink(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scache_t *dscp, cm_req_t *reqp, char *leaf) +cm_IoctlSymlink(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scache_t *dscp, cm_req_t *reqp, clientchar_t *leaf) { afs_int32 code; cm_attr_t tattr; @@ -1725,41 +1829,18 @@ cm_IoctlSymlink(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scache_t *dsc int free_syml = FALSE; if (!(ioctlp->flags & CM_IOCTLFLAG_USEUTF8)) { - /* Translate chars for the link name */ - TranslateExtendedChars(leaf); - /* Translate chars for the linked to name */ TranslateExtendedChars(ioctlp->inDatap); } - symlp = ioctlp->inDatap; /* contents of link */ - - { - char * normalized; - int normalized_len; - - int len = strlen(symlp) + 1; - - normalized_len = cm_NormalizeUtf8String(symlp, len, NULL, 0); - if (normalized_len > len) { - normalized = malloc(normalized_len); - free_syml = TRUE; - } else { - normalized = symlp; - } - - cm_NormalizeUtf8String(symlp, len, normalized, normalized_len); - - if (symlp != normalized) - symlp = normalized; - } - - cp = symlp; + cp = symlp = ioctlp->inDatap; /* contents of link */ #ifdef AFS_FREELANCE_CLIENT if (cm_freelanceEnabled && dscp == cm_data.rootSCachep) { /* we are adding the symlink to the root dir., so call * the freelance code to do the add. */ + fschar_t *fsleaf; + if (cp[0] == cp[1] && cp[1] == '\\' && !_strnicmp(cm_NetbiosName,cp+2,strlen(cm_NetbiosName))) { @@ -1770,8 +1851,11 @@ cm_IoctlSymlink(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scache_t *dsc p += 4; cp = p; } + osi_Log0(afsd_logp,"IoctlCreateSymlink within Freelance root dir"); - code = cm_FreelanceAddSymlink(leaf, cp, NULL); + fsleaf = cm_ClientStringToFsStringAlloc(leaf, -1, NULL); + code = cm_FreelanceAddSymlink(fsleaf, cp, NULL); + free(fsleaf); } else #endif { @@ -1787,10 +1871,6 @@ cm_IoctlSymlink(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scache_t *dsc FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME, dscp, leaf, NULL, TRUE); - - if (free_syml) - free(symlp); - return code; } @@ -1809,6 +1889,7 @@ cm_IoctlListlink(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scache_t *ds char *cp; cm_space_t *spacep; cm_scache_t *newRootScp; + clientchar_t *clientp; if (!(ioctlp->flags & CM_IOCTLFLAG_USEUTF8)) { /* Translate chars for the link name */ @@ -1816,7 +1897,9 @@ cm_IoctlListlink(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scache_t *ds } cp = ioctlp->inDatap; - code = cm_Lookup(dscp, cp, CM_FLAG_NOMOUNTCHASE, userp, reqp, &scp); + clientp = cm_Utf8ToClientStringAlloc(cp, -1, NULL); + code = cm_Lookup(dscp, clientp, CM_FLAG_NOMOUNTCHASE, userp, reqp, &scp); + free(clientp); if (code) return code; @@ -1871,6 +1954,7 @@ cm_IoctlIslink(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scache_t *dscp afs_int32 code; cm_scache_t *scp; char *cp; + clientchar_t *clientp; if (!(ioctlp->flags & CM_IOCTLFLAG_USEUTF8)) { /* Translate chars for the link name */ @@ -1879,7 +1963,9 @@ cm_IoctlIslink(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scache_t *dscp cp = ioctlp->inDatap; osi_LogEvent("cm_IoctlListlink",NULL," name[%s]",cp); - code = cm_Lookup(dscp, cp, CM_FLAG_NOMOUNTCHASE, userp, reqp, &scp); + clientp = cm_Utf8ToClientStringAlloc(cp, -1, NULL); + code = cm_Lookup(dscp, clientp, CM_FLAG_NOMOUNTCHASE, userp, reqp, &scp); + free(clientp); if (code) return code; @@ -1906,6 +1992,7 @@ cm_IoctlDeletelink(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scache_t * char *cp; char * originalName = NULL; cm_dirOp_t dirop; + clientchar_t *clientp; if (!(ioctlp->flags & CM_IOCTLFLAG_USEUTF8)) { /* Translate chars for the link name */ @@ -1913,8 +2000,9 @@ cm_IoctlDeletelink(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scache_t * } cp = ioctlp->inDatap; - code = cm_Lookup(dscp, cp, CM_FLAG_NOMOUNTCHASE, userp, reqp, &scp); - + clientp = cm_Utf8ToClientStringAlloc(cp, -1, NULL); + code = cm_Lookup(dscp, clientp, CM_FLAG_NOMOUNTCHASE, userp, reqp, &scp); + /* if something went wrong, bail out now */ if (code) goto done3; @@ -1939,7 +2027,7 @@ cm_IoctlDeletelink(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scache_t * #ifdef USE_BPLUS code = cm_BeginDirOp(dscp, userp, reqp, CM_DIRLOCK_READ, &dirop); if (code == 0) { - code = cm_BPlusDirLookupOriginalName(&dirop, cp, &originalName); + code = cm_BPlusDirLookupOriginalName(&dirop, clientp, &originalName); /* cm_Dir*() functions can't be used to lookup the original name since those functions only know of the original name. */ @@ -1968,13 +2056,13 @@ cm_IoctlDeletelink(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scache_t * #endif { /* easier to do it this way */ - code = cm_Unlink(dscp, originalName, cp, userp, reqp); + code = cm_Unlink(dscp, originalName, clientp, userp, reqp); } if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH)) smb_NotifyChange(FILE_ACTION_REMOVED, FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME, - dscp, cp, NULL, TRUE); + dscp, clientp, NULL, TRUE); if (originalName != NULL && originalName != cp) { free(originalName); @@ -1991,6 +2079,8 @@ cm_IoctlDeletelink(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scache_t * cm_ReleaseSCache(scp); done3: + free(clientp); + return code; } @@ -2494,7 +2584,6 @@ cm_IoctlMakeSubmount(cm_ioctl_t *ioctlp, cm_user_t *userp) /* Parse the input parameters--first the required afs path, * then the requested submount name (which may be ""). */ - cm_NormalizeAfsPath (afspath, sizeof(afspath), ioctlp->inDatap); submountreqp = ioctlp->inDatap + (strlen(ioctlp->inDatap)+1); /* If the caller supplied a suggested submount name, see if @@ -2513,7 +2602,6 @@ cm_IoctlMakeSubmount(cm_ioctl_t *ioctlp, cm_user_t *userp) NULL ); if (submountreqp && *submountreqp) { - char submountPathNormalized[MAX_PATH]; char submountPath[MAX_PATH]; dwSize = sizeof(submountPath); @@ -2545,8 +2633,7 @@ cm_IoctlMakeSubmount(cm_ioctl_t *ioctlp, cm_user_t *userp) * supplied path matches the submount's path, we can still * use the suggested submount name. */ - cm_NormalizeAfsPath (submountPathNormalized, sizeof(submountPathNormalized), submountPath); - if (!strcmp (submountPathNormalized, afspath)) { + if (!strcmp (submountPath, afspath)) { StringCbCopyA(ioctlp->outDatap, SMB_IOCTL_MAXDATA - (ioctlp->outDatap - ioctlp->outAllocp), submountreqp); ioctlp->outDatap += strlen(ioctlp->outDatap) +1; RegCloseKey( hkSubmounts ); @@ -2579,7 +2666,6 @@ cm_IoctlMakeSubmount(cm_ioctl_t *ioctlp, cm_user_t *userp) nextAutoSubmount = 1; for ( dwIndex = 0; dwIndex < dwSubmounts; dwIndex ++ ) { - char submountPathNormalized[MAX_PATH]; char submountPath[MAX_PATH] = ""; DWORD submountPathLen = sizeof(submountPath); char submountName[MAX_PATH]; @@ -2614,8 +2700,7 @@ cm_IoctlMakeSubmount(cm_ioctl_t *ioctlp, cm_user_t *userp) * that our caller specified. If so, we can return * this submount. */ - cm_NormalizeAfsPath (submountPathNormalized, sizeof(submountPathNormalized), submountPath); - if (!strcmp (submountPathNormalized, afspath)) { + if (!strcmp (submountPath, afspath)) { StringCbCopyA(ioctlp->outDatap, SMB_IOCTL_MAXDATA - (ioctlp->outDatap - ioctlp->outAllocp), submountName); ioctlp->outDatap += strlen(ioctlp->outDatap) +1; RegCloseKey(hkSubmounts); @@ -2804,7 +2889,6 @@ cm_IoctlUUIDControl(struct cm_ioctl * ioctlp, struct cm_user *userp) */ extern int cm_DumpSCache(FILE *outputFile, char *cookie, int lock); extern int cm_DumpBufHashTable(FILE *outputFile, char *cookie, int lock); -extern int smb_DumpVCP(FILE *outputFile, char *cookie, int lock); /* * VIOC_TRACEMEMDUMP internals. @@ -3078,5 +3162,3 @@ cm_IoctlVolStatTest(struct cm_ioctl *ioctlp, struct cm_user *userp) return code; } - - diff --git a/src/WINNT/afsd/cm_ioctl.h b/src/WINNT/afsd/cm_ioctl.h index bb188f2..c2ab26a 100644 --- a/src/WINNT/afsd/cm_ioctl.h +++ b/src/WINNT/afsd/cm_ioctl.h @@ -117,9 +117,9 @@ typedef struct cm_IoctlQueryOptions { #define MAXNUMSYSNAMES 16 /* max that current constants allow */ #define MAXSYSNAME 128 /* max sysname (i.e. @sys) size */ -extern char * cm_sysName; +extern clientchar_t *cm_sysName; extern unsigned int cm_sysNameCount; -extern char * cm_sysNameList[MAXNUMSYSNAMES]; +extern clientchar_t *cm_sysNameList[MAXNUMSYSNAMES]; /* Paths that are passed into pioctl calls can be specified using UTF-8. These strings are prefixed with UTF8_PREFIX defined below. @@ -143,14 +143,21 @@ extern void cm_InitIoctl(void); extern void cm_ResetACLCache(cm_user_t *userp); -extern cm_ioctlQueryOptions_t * cm_IoctlGetQueryOptions(struct cm_ioctl *ioctlp, struct cm_user *userp); +extern cm_ioctlQueryOptions_t * +cm_IoctlGetQueryOptions(struct cm_ioctl *ioctlp, struct cm_user *userp); -extern void cm_IoctlSkipQueryOptions(struct cm_ioctl *ioctlp, struct cm_user *userp); +extern void +cm_IoctlSkipQueryOptions(struct cm_ioctl *ioctlp, struct cm_user *userp); -extern void cm_NormalizeAfsPath(char *outpathp, long outlen, char *inpathp); +extern void +cm_NormalizeAfsPath(clientchar_t *outpathp, long outlen, clientchar_t *inpathp); extern void cm_SkipIoctlPath(cm_ioctl_t *ioctlp); +extern clientchar_t * cm_ParseIoctlStringAlloc(cm_ioctl_t *ioctlp, const char * ext_instrp); + +extern int cm_UnparseIoctlString(cm_ioctl_t *ioctlp, char * ext_outp, const clientchar_t * cstr, int cchlen); + extern afs_int32 cm_IoctlGetACL(cm_ioctl_t *ioctlp, cm_user_t *userp, cm_scache_t *scp, cm_req_t *reqp); extern afs_int32 cm_IoctlGetFileCellName(cm_ioctl_t *ioctlp, cm_user_t *userp, cm_scache_t *scp, cm_req_t *reqp); @@ -205,7 +212,7 @@ extern afs_int32 cm_IoctlGetSPrefs(cm_ioctl_t *ioctlp, cm_user_t *userp); extern afs_int32 cm_IoctlStoreBehind(cm_ioctl_t *ioctlp, cm_user_t *userp); -extern afs_int32 cm_IoctlCreateMountPoint(cm_ioctl_t *ioctlp, cm_user_t *userp, cm_scache_t *dscp, cm_req_t *reqp, char *leaf); +extern afs_int32 cm_IoctlCreateMountPoint(cm_ioctl_t *ioctlp, cm_user_t *userp, cm_scache_t *dscp, cm_req_t *reqp, clientchar_t *leaf); extern afs_int32 cm_CleanFile(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp); @@ -227,7 +234,7 @@ extern afs_int32 cm_IoctlDelToken(cm_ioctl_t *ioctlp, cm_user_t *userp); extern afs_int32 cm_IoctlDelAllToken(cm_ioctl_t *ioctlp, cm_user_t *userp); -extern afs_int32 cm_IoctlSymlink(cm_ioctl_t *ioctlp, cm_user_t *userp, cm_scache_t *dscp, cm_req_t *reqp, char *leaf); +extern afs_int32 cm_IoctlSymlink(cm_ioctl_t *ioctlp, cm_user_t *userp, cm_scache_t *dscp, cm_req_t *reqp, clientchar_t *leaf); extern afs_int32 cm_IoctlIslink(cm_ioctl_t *ioctlp, cm_user_t *userp, cm_scache_t *scp, cm_req_t *reqp); @@ -263,6 +270,8 @@ extern afs_int32 cm_IoctlVolStatTest(struct cm_ioctl *ioctlp, struct cm_user *us extern afs_int32 cm_IoctlUnicodeControl(struct cm_ioctl *ioctlp, struct cm_user * userp); +extern void TranslateExtendedChars(char *str); + #endif /* __CM_IOCTL_INTERFACES_ONLY__ */ #endif /* __CM_IOCTL_H_ENV__ */ diff --git a/src/WINNT/afsd/cm_nls.c b/src/WINNT/afsd/cm_nls.c index cdeb9e3..0e9e48c 100644 --- a/src/WINNT/afsd/cm_nls.c +++ b/src/WINNT/afsd/cm_nls.c @@ -28,12 +28,19 @@ #include #include -#define DEBUG_UNICODE +#include "cm_nls.h" + +#ifdef DEBUG_UNICODE +#include +#endif /* This is part of the Microsoft Internationalized Domain Name Mitigation APIs. */ #include +/* TODO: All the normalization and conversion code should NUL + terminate destination strings. */ + int (WINAPI *pNormalizeString)( __in NORM_FORM NormForm, __in_ecount(cwSrcLength) LPCWSTR lpSrcString, @@ -65,8 +72,15 @@ long cm_InitNormalization(void) return 1; } - pNormalizeString = GetProcAddress(h_Nls, "NormalizeString"); - pIsNormalizedString = GetProcAddress(h_Nls, "IsNormalizedString"); + pNormalizeString = + (int (WINAPI *)( NORM_FORM, LPCWSTR, + int, LPWSTR, int)) + GetProcAddress(h_Nls, "NormalizeString"); + + pIsNormalizedString = + (BOOL + (WINAPI *)( NORM_FORM, LPCWSTR, int )) + GetProcAddress(h_Nls, "IsNormalizedString"); return (pNormalizeString && pIsNormalizedString); } @@ -100,6 +114,13 @@ long cm_InitNormalization(void) static wchar_t * NormalizeUtf16String(const wchar_t * src, int cch_src, wchar_t * ext_dest, int *pcch_dest) { +#ifdef DEBUG_UNICODE + assert (pNormalizeString != NULL && pIsNormalizedString != NULL); +#endif + + if (cch_src == -1) + cch_src = wcslen(src) + 1; + if ((pIsNormalizedString && (*pIsNormalizedString)(AFS_NORM_FORM, src, cch_src)) || (!pNormalizeString)) { @@ -109,7 +130,8 @@ NormalizeUtf16String(const wchar_t * src, int cch_src, wchar_t * ext_dest, int * } /* No need to or unable to normalize. Just copy the string. - Note that the string is not necessarily NULL terminated. */ + Note that the string is not NUL terminated if the source + string is not NUL terminated. */ if (ext_dest) { memcpy(ext_dest, src, cch_src * sizeof(wchar_t)); @@ -169,6 +191,13 @@ NormalizeUtf16String(const wchar_t * src, int cch_src, wchar_t * ext_dest, int * } *pcch_dest = rv; + if (cch_dest > rv) + dest[rv] = 0; + else { + /* Can't NUL terminate */ + cch_dest = max(rv,cch_dest) + NLSERRCCH; + goto cont; + } /* Success! */ return dest; @@ -190,6 +219,111 @@ NormalizeUtf16String(const wchar_t * src, int cch_src, wchar_t * ext_dest, int * } } +/*! \brief Normalize a Unicode string into a newly allocated buffer + + The input string will be normalized using NFC. + + \param[in] s UTF-16 string to be normalized. + + \param[in] cch_src The number of characters in the input string. If + this is -1, then the input string is assumed to be NUL + terminated. + + \param[out] pcch_dest Receives the number of characters copied to + the output buffer. Note that the character count is the number + of wchar_t characters copied, and not the count of Unicode code + points. This includes the terminating NUL if cch_src was -1 or + included the terminating NUL. + + \return A newly allocated buffer holding the normalized string or + NULL if the call failed. + */ +cm_normchar_t * cm_NormalizeStringAlloc(const cm_unichar_t * s, int cch_src, int *pcch_dest) +{ + int cch_dest = 0; + cm_normchar_t * r; + + r = NormalizeUtf16String(s, cch_src, NULL, &cch_dest); + + if (pcch_dest) + *pcch_dest = cch_dest; + + return r; +} + +int cm_NormalizeString(const cm_unichar_t * s, int cch_src, + cm_normchar_t * dest, int cch_dest) +{ + int tcch = cch_dest; + cm_normchar_t * r; + + r = NormalizeUtf16String(s, cch_src, dest, &tcch); + + if (r != dest) { + /* The supplied buffer was insufficient */ + free(r); + return 0; + } else { + return tcch; + } +} + +/*! \brief Convert a UTF-16 string to a UTF-8 string using a newly allocated buffer + + \param[in] s UTF-16 source string + + \param[in] cch_src Number of characters in \a s. This can be set to + -1 if \a s is NUL terminated. + + \param[out] pcch_dest Receives a count of characters that were + copied to the target buffer. + + \return A newly allocated buffer holding the UTF-8 string. + + */ +cm_utf8char_t * cm_Utf16ToUtf8Alloc(const cm_unichar_t * s, int cch_src, int *pcch_dest) +{ + int cch_dest; + cm_utf8char_t * dest; + + cch_dest = WideCharToMultiByte(CP_UTF8, 0, s, cch_src, NULL, 0, NULL, FALSE); + + if (cch_dest == 0) { + if (pcch_dest) + *pcch_dest = cch_dest; + return NULL; + } + + dest = malloc((cch_dest + 1) * sizeof(cm_utf8char_t)); + + WideCharToMultiByte(CP_UTF8, 0, s, cch_src, dest, cch_dest, NULL, FALSE); + dest[cch_dest] = 0; + + if (pcch_dest) + *pcch_dest = cch_dest; + + return dest; +} + +int cm_Utf16ToUtf8(const cm_unichar_t * src, int cch_src, + cm_utf8char_t * dest, int cch_dest) +{ + return WideCharToMultiByte(CP_UTF8, 0, src, cch_src, dest, cch_dest, NULL, FALSE); +} + +int cm_Utf16ToUtf16(const cm_unichar_t * src, int cch_src, + cm_unichar_t * dest, int cch_dest) +{ + if (cch_src == -1) { + StringCchCopyW(dest, cch_dest, src); + return wcslen(dest) + 1; + } else { + int cch_conv = min(cch_src, cch_dest); + memcpy(dest, src, cch_conv * sizeof(cm_unichar_t)); + return cch_conv; + } +} + /* \brief Normalize a UTF-16 string into a UTF-8 string. \param[in] src : Source string. @@ -305,7 +439,7 @@ static const short sanitized_escapes_1252[] = { }; static int sanitize_bytestring(const char * src, int cch_src, - char * odest, int cch_dest) + char * odest, int cch_dest) { char * dest = odest; while (cch_src > 0 && *src && cch_dest > 0) { @@ -348,6 +482,282 @@ static int sanitize_bytestring(const char * src, int cch_src, #undef IS_ESCAPED #undef ESCVAL +long cm_NormalizeUtf8StringToUtf16(const char * src, int cch_src, + wchar_t * dest, int cch_dest) +{ + wchar_t wsrcbuf[NLSMAXCCH]; + wchar_t *wnorm; + int cch; + int cch_norm; + + /* Get some edge cases out first, so we don't have to worry about + cch_src being 0 etc. */ + if (cch_src == 0) { + return 0; + } else if (*src == '\0') { + if (cch_dest >= 1) + *dest = L'\0'; + return 1; + } + + if (cch_src == -1) { + cch_src = strlen(src) + 1; + } + + cch = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, src, + cch_src * sizeof(char), wsrcbuf, NLSMAXCCH); + + if (cch == 0) { + if (GetLastError() == ERROR_NO_UNICODE_TRANSLATION) { + char sanitized[NLSMAXCCH]; + int cch_sanitized; + + /* If src doesn't have a unicode translation, then it + wasn't valid UTF-8. In this case, we assume that src + is CP-1252 and then try to convert again. But before + that, we use a translation table to "sanitize" the + input. */ + + cch_sanitized = sanitize_bytestring(src, cch_src, sanitized, + sizeof(sanitized)/sizeof(char)); + + if (cch_sanitized == 0) { +#ifdef DEBUG_UNICODE + DebugBreak(); +#endif + return 0; + } + + cch = MultiByteToWideChar(1252, 0, sanitized, + cch_sanitized * sizeof(char), wsrcbuf, NLSMAXCCH); + if (cch == 0) { + /* Well, that didn't work either. Something is very wrong. */ +#ifdef DEBUG_UNICODE + DebugBreak(); +#endif + return 0; + } + } else { + return 0; + } + } + + cch_norm = cch_dest; + wnorm = NormalizeUtf16String(wsrcbuf, cch, dest, &cch_norm); + if (wnorm == NULL) { +#ifdef DEBUG_UNICODE + DebugBreak(); +#endif + return 0; + } + + if (wnorm != dest) { + /* The buffer was insufficient */ + if (dest != NULL && cch_dest > 1) { + *dest = L'\0'; + cch_norm = 0; + } + + free(wnorm); + } + + return cch_norm; +} + +cm_normchar_t *cm_NormalizeUtf8StringToUtf16Alloc(const cm_utf8char_t * src, int cch_src, + int *pcch_dest) +{ + wchar_t wsrcbuf[NLSMAXCCH]; + wchar_t *wnorm; + int cch; + int cch_norm; + + /* Get some edge cases out first, so we don't have to worry about + cch_src being 0 etc. */ + if (cch_src == 0) { + return NULL; + } else if (*src == '\0') { + return wcsdup(L""); + } + + if (cch_src == -1) { + cch_src = strlen(src) + 1; + } + + cch = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, src, + cch_src * sizeof(char), wsrcbuf, NLSMAXCCH); + + if (cch == 0) { + if (GetLastError() == ERROR_NO_UNICODE_TRANSLATION) { + char sanitized[NLSMAXCCH]; + int cch_sanitized; + + /* If src doesn't have a unicode translation, then it + wasn't valid UTF-8. In this case, we assume that src + is CP-1252 and then try to convert again. But before + that, we use a translation table to "sanitize" the + input. */ + + cch_sanitized = sanitize_bytestring(src, cch_src, sanitized, + sizeof(sanitized)/sizeof(char)); + + if (cch_sanitized == 0) { +#ifdef DEBUG_UNICODE + DebugBreak(); +#endif + return NULL; + } + + cch = MultiByteToWideChar(1252, 0, sanitized, + cch_sanitized * sizeof(char), wsrcbuf, NLSMAXCCH); + if (cch == 0) { + /* Well, that didn't work either. Something is very wrong. */ +#ifdef DEBUG_UNICODE + DebugBreak(); +#endif + return NULL; + } + } else { + return NULL; + } + } + + cch_norm = 0; + wnorm = NormalizeUtf16String(wsrcbuf, cch, NULL, &cch_norm); + if (wnorm == NULL) { +#ifdef DEBUG_UNICODE + DebugBreak(); +#endif + return NULL; + } + + if (pcch_dest) + *pcch_dest = cch_norm; + + return wnorm; +} + +int cm_Utf8ToUtf16(const cm_utf8char_t * src, int cch_src, + cm_unichar_t * dest, int cch_dest) +{ + int cch; + + if (cch_src == -1) { + cch_src = strlen(src) + 1; + } + + cch = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, src, + cch_src * sizeof(char), dest, cch_dest); + + if (cch == 0) { + if (GetLastError() == ERROR_NO_UNICODE_TRANSLATION) { + char sanitized[NLSMAXCCH]; + int cch_sanitized; + + /* If src doesn't have a unicode translation, then it + wasn't valid UTF-8. In this case, we assume that src + is CP-1252 and then try to convert again. But before + that, we use a translation table to "sanitize" the + input. */ + + cch_sanitized = sanitize_bytestring(src, cch_src, sanitized, + sizeof(sanitized)/sizeof(char)); + + if (cch_sanitized == 0) { +#ifdef DEBUG_UNICODE + DebugBreak(); +#endif + return 0; + } + + cch = MultiByteToWideChar(1252, 0, sanitized, + cch_sanitized * sizeof(char), dest, cch_dest); + if (cch == 0) { + /* Well, that didn't work either. Something is very wrong. */ +#ifdef DEBUG_UNICODE + DebugBreak(); +#endif + return 0; + } else { + return cch; + } + + } else { + return 0; + } + } else { + return cch; + } +} + +cm_unichar_t * cm_Utf8ToUtf16Alloc(const cm_utf8char_t * src, int cch_src, int *pcch_dest) +{ + cm_unichar_t * ustr = NULL; + int cch; + + if (cch_src == -1) { + cch_src = strlen(src) + 1; + } + + cch = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, src, + cch_src * sizeof(char), NULL, 0); + + if (cch == 0) { + if (GetLastError() == ERROR_NO_UNICODE_TRANSLATION) { + char sanitized[NLSMAXCCH]; + int cch_sanitized; + + /* If src doesn't have a unicode translation, then it + wasn't valid UTF-8. In this case, we assume that src + is CP-1252 and then try to convert again. But before + that, we use a translation table to "sanitize" the + input. */ + + cch_sanitized = sanitize_bytestring(src, cch_src, sanitized, + sizeof(sanitized)/sizeof(char)); + + if (cch_sanitized == 0) { +#ifdef DEBUG_UNICODE + DebugBreak(); +#endif + return NULL; + } + + cch = MultiByteToWideChar(1252, 0, sanitized, + cch_sanitized * sizeof(char), NULL, 0); + if (cch == 0) { + /* Well, that didn't work either. Something is very wrong. */ +#ifdef DEBUG_UNICODE + DebugBreak(); +#endif + return NULL; + } + + ustr = malloc((cch + 1) * sizeof(wchar_t)); + + cch = MultiByteToWideChar(1252, 0, sanitized, + cch_sanitized * sizeof(char), ustr, cch); + ustr[cch] = 0; + } else { + return NULL; + } + } else { + + ustr = malloc((cch + 1) * sizeof(wchar_t)); + + cch = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, src, + cch_src * sizeof(char), ustr, cch); + ustr[cch] = 0; + } + + if (pcch_dest) + *pcch_dest = cch; + + return ustr; +} + + + /* \brief Normalize a UTF-8 string. \param[in] src String to normalize. @@ -391,7 +801,7 @@ long cm_NormalizeUtf8String(const char * src, int cch_src, cch_src = strlen(src) + 1; } - cch = MultiByteToWideChar(CP_UTF8, 0, src, + cch = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, src, cch_src * sizeof(char), wsrcbuf, NLSMAXCCH); if (cch == 0) { @@ -465,7 +875,7 @@ int cm_strnicmp_utf8(const char * str1, const char * str2, int n) wchar_t wstr2[NLSMAXCCH]; int rv; - /* first check for NULL pointers */ + /* first check for NULL pointers (assume NULL < "") */ if (str1 == NULL) { if (str2 == NULL) return 0; @@ -475,7 +885,7 @@ int cm_strnicmp_utf8(const char * str1, const char * str2, int n) return 1; } - len1 = MultiByteToWideChar(CP_UTF8, 0, str1, n, wstr1, NLSMAXCCH); + len1 = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, str1, n, wstr1, NLSMAXCCH); if (len1 == 0) { #ifdef DEBUG DebugBreak(); @@ -483,7 +893,7 @@ int cm_strnicmp_utf8(const char * str1, const char * str2, int n) wstr1[0] = L'\0'; } - len2 = MultiByteToWideChar(CP_UTF8, 0, str2, n, wstr2, NLSMAXCCH); + len2 = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, str2, n, wstr2, NLSMAXCCH); if (len2 == 0) { #ifdef DEBUG DebugBreak(); @@ -502,6 +912,97 @@ int cm_strnicmp_utf8(const char * str1, const char * str2, int n) } } +int cm_strnicmp_utf16(const cm_unichar_t * str1, const cm_unichar_t * str2, int len) +{ + int rv; + size_t cch1; + size_t cch2; + + /* first check for NULL pointers */ + if (str1 == NULL) { + if (str2 == NULL) + return 0; + else + return -1; + } else if (str2 == NULL) { + return 1; + } + + if (FAILED(StringCchLengthW(str1, len, &cch1))) + cch1 = len; + + if (FAILED(StringCchLengthW(str2, len, &cch2))) + cch2 = len; + + rv = CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, str1, cch1, str2, cch2); + if (rv > 0) + return (rv - 2); + else { +#ifdef DEBUG + DebugBreak(); +#endif + return 0; + } +} + +int cm_stricmp_utf16(const cm_unichar_t * str1, const cm_unichar_t * str2) +{ + int rv; + + /* first check for NULL pointers */ + if (str1 == NULL) { + if (str2 == NULL) + return 0; + else + return -1; + } else if (str2 == NULL) { + return 1; + } + + rv = CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, str1, -1, str2, -1); + if (rv > 0) + return (rv - 2); + else { +#ifdef DEBUG + DebugBreak(); +#endif + return 0; + } +} + +cm_unichar_t *cm_strlwr_utf16(cm_unichar_t * str) +{ + int rv; + int len; + + len = wcslen(str) + 1; + rv = LCMapStringW(LOCALE_INVARIANT, LCMAP_LOWERCASE, str, len, str, len); +#ifdef DEBUG + if (rv == 0) { + DebugBreak(); + } +#endif + + return str; +} + +cm_unichar_t *cm_strupr_utf16(cm_unichar_t * str) +{ + int rv; + int len; + + len = wcslen(str) + 1; + rv = LCMapStringW(LOCALE_INVARIANT, LCMAP_UPPERCASE, str, len, str, len); +#ifdef DEBUG + if (rv == 0) { + DebugBreak(); + } +#endif + + return str; +} + + int cm_stricmp_utf8(const char * str1, const char * str2) { wchar_t wstr1[NLSMAXCCH]; @@ -520,7 +1021,7 @@ int cm_stricmp_utf8(const char * str1, const char * str2) return 1; } - len1 = MultiByteToWideChar(CP_UTF8, 0, str1, -1, wstr1, NLSMAXCCH); + len1 = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, str1, -1, wstr1, NLSMAXCCH); if (len1 == 0) { #ifdef DEBUG DebugBreak(); @@ -528,7 +1029,7 @@ int cm_stricmp_utf8(const char * str1, const char * str2) wstr1[0] = L'\0'; } - len2 = MultiByteToWideChar(CP_UTF8, 0, str2, -1, wstr2, NLSMAXCCH); + len2 = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, str2, -1, wstr2, NLSMAXCCH); if (len2 == 0) { #ifdef DEBUG DebugBreak(); @@ -547,6 +1048,7 @@ int cm_stricmp_utf8(const char * str1, const char * str2) } } +#if 0 wchar_t * strupr_utf16(wchar_t * wstr, size_t cbstr) { wchar_t wstrd[NLSMAXCCH]; @@ -558,15 +1060,15 @@ wchar_t * strupr_utf16(wchar_t * wstr, size_t cbstr) return wstr; } +#endif char * strupr_utf8(char * str, size_t cbstr) { wchar_t wstr[NLSMAXCCH]; wchar_t wstrd[NLSMAXCCH]; int len; - int r; - len = MultiByteToWideChar(CP_UTF8, 0, str, -1, wstr, NLSMAXCCH); + len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, str, -1, wstr, NLSMAXCCH); if (len == 0) return str; @@ -618,3 +1120,31 @@ char * char_prev_utf8(const char * c) #undef CH } + +wchar_t * char_next_utf16(const wchar_t * c) +{ + unsigned short sc = (unsigned short) *c; + + if (sc >= 0xd800 && sc <= 0xdbff) + return (wchar_t *) c+2; + return (wchar_t *) c+1; +} + +wchar_t * char_prev_utf16(const wchar_t * c) +{ + unsigned short sc = (unsigned short) *(--c); + + if (sc >= 0xdc00 && sc <= 0xdfff) + return (wchar_t *) --c; + return (wchar_t *) c; +} + +wchar_t * char_this_utf16(const wchar_t * c) +{ + unsigned short sc = (unsigned short) *c; + + if (sc >= 0xdc00 && sc <= 0xdfff) + return (wchar_t *) --c; + return (wchar_t *) c; +} + diff --git a/src/WINNT/afsd/cm_nls.h b/src/WINNT/afsd/cm_nls.h index ba7add3..017d271 100644 --- a/src/WINNT/afsd/cm_nls.h +++ b/src/WINNT/afsd/cm_nls.h @@ -25,29 +25,239 @@ #ifndef __CM_NLS_H_ENV__ #define __CM_NLS_H_ENV__ +/* Character types + + There are three character types that we use as implementation + types. These should generally only be referenced by the + nationalization code. + + - ::cm_unichar_t + + - ::cm_normchar_t + + - ::cm_utf8char_t + + The character types that are used by code are : + + - ::clientchar_t + + - ::normchar_t + + - ::fschar_t + + */ + +/*! \brief Unicode UTF-16 Character */ +typedef wchar_t cm_unichar_t; + +/*! \brief Unicode UTF-16 Normalized Character (NF-C) */ +typedef wchar_t cm_normchar_t; + +/*! \brief Unicode UTF-8 Character */ +typedef unsigned char cm_utf8char_t; + +/*! \brief Client name */ +typedef cm_unichar_t clientchar_t; + +/*! \brief File Server name */ +typedef cm_utf8char_t fschar_t; + +/*! \brief Normalized name */ +typedef cm_normchar_t normchar_t; + +#define __paste(a,b) a ## b +#define _C(s) __paste(L,s) +#define _FS(s) s +#define _N(s) __paste(L,s) + +#define cm_ClientStringToNormStringAlloc cm_NormalizeStringAlloc +#define cm_ClientStringToFsStringAlloc cm_Utf16ToUtf8Alloc +#define cm_ClientStringToUtf8Alloc cm_Utf16ToUtf8Alloc +#define cm_FsStringToClientStringAlloc cm_Utf8ToUtf16Alloc +#define cm_FsStringToNormStringAlloc cm_NormalizeUtf8StringToUtf16Alloc +#define cm_Utf8ToNormStringAlloc cm_NormalizeUtf8StringToUtf16Alloc +#define cm_Utf8ToClientStringAlloc cm_Utf8ToUtf16Alloc + +#define cm_ClientStringToUtf16 cm_Utf16ToUtf16 +#define cm_ClientStringToUtf8 cm_Utf16ToUtf8 +#define cm_ClientStringToFsString cm_Utf16ToUtf8 +#define cm_ClientStringToNormString cm_NormalizeString +#define cm_FsStringToClientString cm_Utf8ToUtf16 +#define cm_FsStringToNormString cm_NormalizeUtf8StringToUtf16 +#define cm_Utf8ToClientString cm_Utf8ToUtf16 +#define cm_OemToClientString(s,cchs,d,cchd) MultiByteToWideChar(CP_OEMCP, 0, s, cchs, d, cchd) +#define cm_AnsiToClientString(s,cchs,d,cchd) MultiByteToWideChar(CP_ACP, 0, s, cchs, d, cchd) + +#define cm_ClientStrCmp wcscmp +#define cm_ClientStrCmpI cm_stricmp_utf16 +#define cm_ClientStrCmpIA cm_stricmp_utf16 +#define cm_ClientStrCmpNI cm_strnicmp_utf16 +#define cm_ClientStrCmpN wcsncmp +#define cm_ClientStrChr wcschr +#define cm_ClientStrRChr wcsrchr +#define cm_ClientStrCpy(d,cch,s) StringCchCopyW(d,cch,s) +#define cm_ClientStrCpyN(d,cch,s,n) StringCchCopyNW(d,cch,s,n) +#define cm_ClientStrDup wcsdup +#define cm_ClientStrCat(d,cch,s) StringCchCatW(d,cch,s) +#define cm_ClientStrCatN(d,cch,s,n) StringCchCatNW(d,cch,s,n) +#define cm_ClientStrPrintfN StringCchPrintfW +#define cm_ClientStrPrintfV StringCchVPrintfW +//#define cm_ClientStrPrintf swprintf +#define cm_ClientStrLen wcslen +#define cm_ClientStrLwr cm_strlwr_utf16 +#define cm_ClientStrUpr cm_strupr_utf16 +#define cm_ClientStrSpn wcsspn +#define cm_ClientStrCSpn wcscspn +#define osi_LogSaveClientString osi_LogSaveStringW +#define cm_ClientCharThis char_this_utf16 +#define cm_ClientCharNext char_next_utf16 +#define cm_ClientCharPrev char_prev_utf16 + +#define cm_FsStrDup strdup +#define cm_FsStrLen strlen +#define cm_FsStrCat StringCchCatA +#define cm_FsStrPrintf StringCchPrintfA +#define cm_FsStrRChr strrchr +#define cm_FsStrChr strchr +#define cm_FsStrCmpIA cm_stricmp_utf8 +#define cm_FsStrCmpI cm_stricmp_utf8 +#define cm_FsStrCmpA strcmp +#define cm_FsStrCmp strcmp +#define cm_FsStrCpy(d,cch,s) StringCchCopyA(d,cch,s) +#define osi_LogSaveFsString osi_LogSaveString +#define cm_FsStrCpyN(d,cch,s,n) StringCchCopyN(d,cch,s,n) + +#define cm_NormStrDup wcsdup +#define cm_NormStrCmpI cm_stricmp_utf16 +#define cm_NormStrCmp wcscmp +#define cm_NormCharUpr towupper + +#define cm_Utf16ToClientString cm_Utf16ToUtf16 + extern long cm_InitNormalization(void); -extern long cm_NormalizeUtf16StringToUtf8(const wchar_t * src, int cch_src, - char * adest, int cch_adest); +/* Functions annotated in accordance with sal.h */ + +extern __out_ecount_full_z(*pcch_dest) __checkReturn __success(return != NULL) cm_normchar_t * + cm_NormalizeStringAlloc + (__in_ecount(cch_src) const cm_unichar_t * s, + int cch_src, + __out_ecount_full_opt(1) int *pcch_dest); + +extern __success(return != 0) int + cm_NormalizeString + (__in_ecount(cch_src) const cm_unichar_t * s, + int cch_src, + __out_ecount_full_z_opt(cch_dest) cm_normchar_t * dest, + int cch_dest); + +extern __out_ecount_full_z(*pcch_dest) __checkReturn __success(return != NULL) cm_utf8char_t * + cm_Utf16ToUtf8Alloc + (__in_ecount(cch_src) const cm_unichar_t * s, + int cch_src, + __out_ecount_full_opt(1) int *pcch_dest); + +extern __out_ecount_full_z(*pcch_dest) __checkReturn __success(return != NULL) cm_unichar_t * + cm_Utf8ToUtf16Alloc + (__in_ecount(cch_src) const cm_utf8char_t * src, + int cch_src, + __out_ecount_full_opt(1) int *pcch_dest); + +extern __success(return != 0) long + cm_NormalizeUtf8StringToUtf16 + (__in_ecount(cch_src) const char * src, + int cch_src, + __out_ecount_full_z_opt(cch_dest) cm_normchar_t * dest, + int cch_dest); + +extern __out_ecount_full_z(*pcch_dest) __checkReturn __success(return != NULL) cm_normchar_t * + cm_NormalizeUtf8StringToUtf16Alloc + (__in_ecount(cch_src) const cm_utf8char_t * src, + int cch_src, + __out_ecount_full_opt(1) int *pcch_dest); + +extern __success(return != 0) int + cm_Utf8ToUtf16 + (__in_ecount(cch_src) const cm_utf8char_t * src, + int cch_src, + __out_ecount_full_z_opt(cch_dest) cm_unichar_t * dest, + int cch_dest); + +extern __success(return != 0) int + cm_Utf16ToUtf8 + (__in_ecount(cch_src) const cm_unichar_t * src, + int cch_src, + __out_ecount_full_z_opt(cch_dest) cm_utf8char_t * dest, + int cch_dest); + +extern __success(return != 0) int + cm_Utf16ToUtf16 + (__in_ecount(cch_src) const cm_unichar_t * src, + int cch_src, + __out_ecount_full_z_opt(cch_dest) cm_unichar_t * dest, + int cch_dest); + +extern int + cm_strnicmp_utf16 + (__in_z const cm_unichar_t * str1, + __in_z const cm_unichar_t * str2, + int len); -extern long cm_NormalizeUtf8String(const char * src, int cch_src, - char * adest, int cch_adest); +extern int + cm_stricmp_utf16 + (__in_z const cm_unichar_t * str1, + __in_z const cm_unichar_t * str2); /* The cm_stricmp_utf8N function is identical to cm_stricmp_utf8 except it is used in instances where one of the strings is always known to be ASCII. */ -extern int cm_stricmp_utf8N(const char * str1, const char * str2); +extern int + cm_stricmp_utf8N + (__in_z const char * str1, + __in_z const char * str2); #define cm_stricmp_utf8N cm_stricmp_utf8 -extern int cm_stricmp_utf8(const char * str1, const char * str2); +extern int + cm_stricmp_utf8 + (__in_z const char * str1, + __in_z const char * str2); /* The cm_strnicmp_utf8N function is identical to cm_strnicmp_utf8 except it is used in instances where one of the strings is always known to be ASCII. */ -extern int cm_strnicmp_utf8N(const char * str1, const char * str2, int n); +extern int + cm_strnicmp_utf8N + (__in_z const char * str1, + __in_z const char * str2, int n); #define cm_strnicmp_utf8N cm_strnicmp_utf8 -extern int cm_strnicmp_utf8(const char * str1, const char * str2, int n); +extern int + cm_strnicmp_utf8 + (__in_z const char * str1, + __in_z const char * str2, int n); + +extern __out_z wchar_t * +char_next_utf16 +(__in_z const wchar_t * c); + +extern __out_z wchar_t * +char_prev_utf16 +(__in_z const wchar_t * c); + +extern __out_z wchar_t * +char_this_utf16 +(__in_z const wchar_t * c); + +extern __out_z cm_unichar_t * +cm_strlwr_utf16(__inout_z cm_unichar_t * str); + +extern __out_z cm_unichar_t * +cm_strupr_utf16(__inout_z cm_unichar_t * str); + +#if 0 + +extern long cm_NormalizeUtf16StringToUtf8(const wchar_t * src, int cch_src, + char * adest, int cch_adest); extern char * char_next_utf8(const char * c); @@ -56,3 +266,6 @@ extern char * char_prev_utf8(const char * c); extern char * strupr_utf8(char * str, size_t cbstr); #endif + +#define lengthof(a) (sizeof(a)/sizeof(a[0])) +#endif diff --git a/src/WINNT/afsd/cm_scache.h b/src/WINNT/afsd/cm_scache.h index ac4990b..2320807 100644 --- a/src/WINNT/afsd/cm_scache.h +++ b/src/WINNT/afsd/cm_scache.h @@ -407,4 +407,6 @@ extern long cm_RecycleSCache(cm_scache_t *scp, afs_int32 flags); extern void cm_RemoveSCacheFromHashTable(cm_scache_t *scp); extern void cm_AdjustScacheLRU(cm_scache_t *scp); + +extern int cm_DumpSCache(FILE *outputFile, char *cookie, int lock); #endif /* __CM_SCACHE_H_ENV__ */ diff --git a/src/WINNT/afsd/cm_user.h b/src/WINNT/afsd/cm_user.h index 361bec1..9284934 100644 --- a/src/WINNT/afsd/cm_user.h +++ b/src/WINNT/afsd/cm_user.h @@ -31,7 +31,7 @@ typedef struct cm_ucell { int gen; /* generation number */ int iterator; /* for use as ListTokens cookie */ long flags; /* flags */ - char userName[MAXKTCNAMELEN]; /* user name */ + fschar_t userName[MAXKTCNAMELEN]; /* user name */ #ifdef QUERY_AFSID afs_uint32 uid; /* User's AFS ID in this cell */ #endif diff --git a/src/WINNT/afsd/cm_utils.c b/src/WINNT/afsd/cm_utils.c index 68b03de..bb849b3 100644 --- a/src/WINNT/afsd/cm_utils.c +++ b/src/WINNT/afsd/cm_utils.c @@ -363,3 +363,372 @@ void cm_FreeSpace(cm_space_t *tsp) lock_ReleaseWrite(&cm_utilsLock); } +/* characters that are legal in an 8.3 name */ +/* + * We used to have 1's for all characters from 128 to 254. But + * the NT client behaves better if we create an 8.3 name for any + * name that has a character with the high bit on, and if we + * delete those characters from 8.3 names. In particular, see + * Sybase defect 10859. + */ +char cm_LegalChars[256] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +#define ISLEGALCHAR(c) ((c) < 256 && (c) > 0 && cm_LegalChars[(c)] != 0) + +/* return true iff component is a valid 8.3 name */ +int cm_Is8Dot3(clientchar_t *namep) +{ + int sawDot = 0; + clientchar_t tc; + int charCount = 0; + + /* + * can't have a leading dot; + * special case for . and .. + */ + if (namep[0] == '.') { + if (namep[1] == 0) + return 1; + if (namep[1] == '.' && namep[2] == 0) + return 1; + return 0; + } + while (tc = *namep++) { + if (tc == '.') { + /* saw another dot */ + if (sawDot) return 0; /* second dot */ + sawDot = 1; + charCount = 0; + continue; + } + if (!ISLEGALCHAR(tc)) + return 0; + charCount++; + if (!sawDot && charCount > 8) + /* more than 8 chars in name */ + return 0; + if (sawDot && charCount > 3) + /* more than 3 chars in extension */ + return 0; + } + return 1; +} + +/* + * Number unparsing map for generating 8.3 names; + * The version taken from DFS was on drugs. + * You can't include '&' and '@' in a file name. + */ +char cm_8Dot3Mapping[42] = +{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', + 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', + 'V', 'W', 'X', 'Y', 'Z', '_', '-', '$', '#', '!', '+', '=' +}; +int cm_8Dot3MapSize = sizeof(cm_8Dot3Mapping); + +void cm_Gen8Dot3NameInt(const fschar_t * longname, cm_dirFid_t * pfid, + clientchar_t *shortName, clientchar_t **shortNameEndp) +{ + char number[12]; + int i, nsize = 0; + int vnode = ntohl(pfid->vnode); + char *lastDot; + int validExtension = 0; + char tc, *temp; + const char *name; + + /* Unparse the file's vnode number to get a "uniquifier" */ + do { + number[nsize] = cm_8Dot3Mapping[vnode % cm_8Dot3MapSize]; + nsize++; + vnode /= cm_8Dot3MapSize; + } while (vnode); + + /* + * Look for valid extension. There has to be a dot, and + * at least one of the characters following has to be legal. + */ + lastDot = strrchr(longname, '.'); + if (lastDot) { + temp = lastDot; temp++; + while (tc = *temp++) + if (ISLEGALCHAR(tc)) + break; + if (tc) + validExtension = 1; + } + + /* Copy name characters */ + for (i = 0, name = longname; + i < (7 - nsize) && name != lastDot; ) { + tc = *name++; + + if (tc == 0) + break; + if (!ISLEGALCHAR(tc)) + continue; + i++; + *shortName++ = toupper(tc); + } + + /* tilde */ + *shortName++ = '~'; + + /* Copy uniquifier characters */ + for (i=0; i < nsize; i++) { + *shortName++ = number[i]; + } + + if (validExtension) { + /* Copy extension characters */ + *shortName++ = *lastDot++; /* copy dot */ + for (i = 0, tc = *lastDot++; + i < 3 && tc; + tc = *lastDot++) { + if (ISLEGALCHAR(tc)) { + i++; + *shortName++ = toupper(tc); + } + } + } + + /* Trailing null */ + *shortName = 0; + + if (shortNameEndp) + *shortNameEndp = shortName; +} + +void cm_Gen8Dot3NameIntW(const clientchar_t * longname, cm_dirFid_t * pfid, + clientchar_t *shortName, clientchar_t **shortNameEndp) +{ + clientchar_t number[12]; + int i, nsize = 0; + int vnode = ntohl(pfid->vnode); + clientchar_t *lastDot; + int validExtension = 0; + clientchar_t tc, *temp; + const clientchar_t *name; + + /* Unparse the file's vnode number to get a "uniquifier" */ + do { + number[nsize] = cm_8Dot3Mapping[vnode % cm_8Dot3MapSize]; + nsize++; + vnode /= cm_8Dot3MapSize; + } while (vnode); + + /* + * Look for valid extension. There has to be a dot, and + * at least one of the characters following has to be legal. + */ + lastDot = cm_ClientStrRChr(longname, '.'); + if (lastDot) { + temp = lastDot; temp++; + while (tc = *temp++) + if (ISLEGALCHAR(tc)) + break; + if (tc) + validExtension = 1; + } + + /* Copy name characters */ + for (i = 0, name = longname; + i < (7 - nsize) && name != lastDot; ) { + tc = *name++; + + if (tc == 0) + break; + if (!ISLEGALCHAR(tc)) + continue; + i++; + *shortName++ = toupper((char) tc); + } + + /* tilde */ + *shortName++ = '~'; + + /* Copy uniquifier characters */ + for (i=0; i < nsize; i++) { + *shortName++ = number[i]; + } + + if (validExtension) { + /* Copy extension characters */ + *shortName++ = *lastDot++; /* copy dot */ + for (i = 0, tc = *lastDot++; + i < 3 && tc; + tc = *lastDot++) { + if (ISLEGALCHAR(tc)) { + i++; + *shortName++ = toupper(tc); + } + } + } + + /* Trailing null */ + *shortName = 0; + + if (shortNameEndp) + *shortNameEndp = shortName; +} + +/*! \brief Compare 'pattern' (containing metacharacters '*' and '?') with the file name 'name'. + + \note This procedure works recursively calling itself. + + \param[in] pattern string containing metacharacters. + \param[in] name File name to be compared with 'pattern'. + + \return BOOL : TRUE/FALSE (match/mistmatch) +*/ +static BOOL +szWildCardMatchFileName(clientchar_t * pattern, clientchar_t * name, int casefold) +{ + clientchar_t upattern[MAX_PATH]; + clientchar_t uname[MAX_PATH]; + + clientchar_t * pename; // points to the last 'name' character + clientchar_t * p; + clientchar_t * pattern_next; + + if (casefold) { + cm_ClientStrCpy(upattern, lengthof(upattern), pattern); + cm_ClientStrUpr(upattern); + pattern = upattern; + + cm_ClientStrCpy(uname, lengthof(uname), name); + cm_ClientStrUpr(uname); + name = uname; + + /* The following translations all work on single byte + characters */ + for (p=upattern; *p; p++) { + if (*p == '"') *p = '.'; continue; + if (*p == '<') *p = '*'; continue; + if (*p == '>') *p = '?'; continue; + } + + for (p=uname; *p; p++) { + if (*p == '"') *p = '.'; continue; + if (*p == '<') *p = '*'; continue; + if (*p == '>') *p = '?'; continue; + } + } + + pename = cm_ClientCharThis(name + cm_ClientStrLen(name)); + + while (*name) { + switch (*pattern) { + case '?': + pattern = cm_ClientCharNext(pattern); + if (*name == '.') + continue; + name = cm_ClientCharNext(name); + break; + + case '*': + pattern = cm_ClientCharNext(pattern); + if (*pattern == '\0') + return TRUE; + + pattern_next = cm_ClientCharNext(pattern); + + for (p = pename; p >= name; p = cm_ClientCharPrev(p)) { + if (*p == *pattern && + szWildCardMatchFileName(pattern_next, + cm_ClientCharNext(p), FALSE)) + return TRUE; + } /* endfor */ + return FALSE; + + default: + if (*name != *pattern) + return FALSE; + pattern = cm_ClientCharNext(pattern); + name = cm_ClientCharNext(name); + break; + } /* endswitch */ + } /* endwhile */ + + /* if all we have left are wildcards, then we match */ + for (;*pattern; pattern = cm_ClientCharNext(pattern)) { + if (*pattern != '*' && *pattern != '?') + return FALSE; + } + return TRUE; +} + +/* do a case-folding search of the star name mask with the name in namep. + * Return 1 if we match, otherwise 0. + */ +int cm_MatchMask(clientchar_t *namep, clientchar_t *maskp, int flags) +{ + clientchar_t * newmask; + int i, j, star, qmark, casefold, retval; + + /* make sure we only match 8.3 names, if requested */ + if ((flags & CM_FLAG_8DOT3) && !cm_Is8Dot3(namep)) + return 0; + + casefold = (flags & CM_FLAG_CASEFOLD) ? 1 : 0; + + /* optimize the pattern: + * if there is a mixture of '?' and '*', + * for example the sequence "*?*?*?*" + * must be turned into the form "*" + */ + newmask = (clientchar_t *)malloc((cm_ClientStrLen(maskp)+1)*sizeof(clientchar_t)); + for ( i=0, j=0, star=0, qmark=0; maskp[i]; i++) { + switch ( maskp[i] ) { + case '?': + case '>': + qmark++; + break; + case '<': + case '*': + star++; + break; + default: + if ( star ) { + newmask[j++] = '*'; + } else if ( qmark ) { + while ( qmark-- ) + newmask[j++] = '?'; + } + newmask[j++] = maskp[i]; + star = 0; + qmark = 0; + } + } + if ( star ) { + newmask[j++] = '*'; + } else if ( qmark ) { + while ( qmark-- ) + newmask[j++] = '?'; + } + newmask[j++] = '\0'; + + retval = szWildCardMatchFileName(newmask, namep, casefold) ? 1:0; + + free(newmask); + return retval; +} + diff --git a/src/WINNT/afsd/cm_utils.h b/src/WINNT/afsd/cm_utils.h index a157d92..eced1a0 100644 --- a/src/WINNT/afsd/cm_utils.h +++ b/src/WINNT/afsd/cm_utils.h @@ -12,8 +12,11 @@ #define CM_UTILS_SPACESIZE 8192 /* space to allocate */ typedef struct cm_space { - char data[CM_UTILS_SPACESIZE]; - struct cm_space *nextp; + union { + clientchar_t wdata[CM_UTILS_SPACESIZE]; + char data[CM_UTILS_SPACESIZE]; + }; + struct cm_space *nextp; } cm_space_t; /* error code hack */ @@ -30,4 +33,22 @@ extern long cm_MapRPCErrorRmdir(long error, cm_req_t *reqp); extern long cm_MapVLRPCError(long error, cm_req_t *reqp); +extern void init_et_to_sys_error(void); + +extern int cm_Is8Dot3(clientchar_t *namep); + +extern void cm_Gen8Dot3Name(struct cm_dirEntry *dep, clientchar_t *shortName, + clientchar_t **shortNameEndp); + +#define cm_Gen8Dot3Name(dep,shortName,shortNameEndp) \ +cm_Gen8Dot3NameInt((dep)->name, &(dep)->fid, shortName, shortNameEndp) + +extern void cm_Gen8Dot3NameInt(const fschar_t * longname, cm_dirFid_t * pfid, + clientchar_t *shortName, clientchar_t **shortNameEndp); + +extern void cm_Gen8Dot3NameIntW(const clientchar_t* longname, cm_dirFid_t * pfid, + clientchar_t *shortName, clientchar_t **shortNameEndp); + +extern int cm_MatchMask(clientchar_t *namep, clientchar_t *maskp, int flags); + #endif /* __CM_UTILS_H_ENV__ */ diff --git a/src/WINNT/afsd/cm_vnodeops.c b/src/WINNT/afsd/cm_vnodeops.c index 7116555..4ec27a1 100644 --- a/src/WINNT/afsd/cm_vnodeops.c +++ b/src/WINNT/afsd/cm_vnodeops.c @@ -24,6 +24,8 @@ #include "smb.h" #include "cm_btree.h" +#include + #ifdef DEBUG extern void afsi_log(char *pattern, ...); #endif @@ -97,156 +99,7 @@ int cm_stricmp(const char *str1, const char *str2) } } -/* characters that are legal in an 8.3 name */ -/* - * We used to have 1's for all characters from 128 to 254. But - * the NT client behaves better if we create an 8.3 name for any - * name that has a character with the high bit on, and if we - * delete those characters from 8.3 names. In particular, see - * Sybase defect 10859. - */ -char cm_LegalChars[256] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -/* return true iff component is a valid 8.3 name */ -int cm_Is8Dot3(char *namep) -{ - int sawDot = 0; - unsigned char tc; - int charCount = 0; - - /* - * can't have a leading dot; - * special case for . and .. - */ - if (namep[0] == '.') { - if (namep[1] == 0) - return 1; - if (namep[1] == '.' && namep[2] == 0) - return 1; - return 0; - } - while (tc = *namep++) { - if (tc == '.') { - /* saw another dot */ - if (sawDot) return 0; /* second dot */ - sawDot = 1; - charCount = 0; - continue; - } - if (cm_LegalChars[tc] == 0) - return 0; - charCount++; - if (!sawDot && charCount > 8) - /* more than 8 chars in name */ - return 0; - if (sawDot && charCount > 3) - /* more than 3 chars in extension */ - return 0; - } - return 1; -} - -/* - * Number unparsing map for generating 8.3 names; - * The version taken from DFS was on drugs. - * You can't include '&' and '@' in a file name. - */ -char cm_8Dot3Mapping[42] = -{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', - 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', - 'V', 'W', 'X', 'Y', 'Z', '_', '-', '$', '#', '!', '+', '=' -}; -int cm_8Dot3MapSize = sizeof(cm_8Dot3Mapping); -void cm_Gen8Dot3NameInt(const char * longname, cm_dirFid_t * pfid, - char *shortName, char **shortNameEndp) -{ - char number[12]; - int i, nsize = 0; - int vnode = ntohl(pfid->vnode); - char *lastDot; - int validExtension = 0; - char tc, *temp; - const char *name; - - /* Unparse the file's vnode number to get a "uniquifier" */ - do { - number[nsize] = cm_8Dot3Mapping[vnode % cm_8Dot3MapSize]; - nsize++; - vnode /= cm_8Dot3MapSize; - } while (vnode); - - /* - * Look for valid extension. There has to be a dot, and - * at least one of the characters following has to be legal. - */ - lastDot = strrchr(longname, '.'); - if (lastDot) { - temp = lastDot; temp++; - while (tc = *temp++) - if (cm_LegalChars[tc]) - break; - if (tc) - validExtension = 1; - } - - /* Copy name characters */ - for (i = 0, name = longname; - i < (7 - nsize) && name != lastDot; ) { - tc = *name++; - - if (tc == 0) - break; - if (!cm_LegalChars[tc]) - continue; - i++; - *shortName++ = toupper(tc); - } - - /* tilde */ - *shortName++ = '~'; - - /* Copy uniquifier characters */ - memcpy(shortName, number, nsize); - shortName += nsize; - - if (validExtension) { - /* Copy extension characters */ - *shortName++ = *lastDot++; /* copy dot */ - for (i = 0, tc = *lastDot++; - i < 3 && tc; - tc = *lastDot++) { - if (cm_LegalChars[tc]) { - i++; - *shortName++ = toupper(tc); - } - } - } - - /* Trailing null */ - *shortName = 0; - - if (shortNameEndp) - *shortNameEndp = shortName; -} /* return success if we can open this file in this mode */ long cm_CheckOpen(cm_scache_t *scp, int openMode, int trunc, cm_user_t *userp, @@ -576,8 +429,8 @@ long cm_CheckNTDelete(cm_scache_t *dscp, cm_scache_t *scp, cm_user_t *userp, * cm_lookupSearch_t object. */ long cm_ApplyDir(cm_scache_t *scp, cm_DirFuncp_t funcp, void *parmp, - osi_hyper_t *startOffsetp, cm_user_t *userp, cm_req_t *reqp, - cm_scache_t **retscp) + osi_hyper_t *startOffsetp, cm_user_t *userp, cm_req_t *reqp, + cm_scache_t **retscp) { char *tp; long code; @@ -647,7 +500,7 @@ long cm_ApplyDir(cm_scache_t *scp, cm_DirFuncp_t funcp, void *parmp, if (code == 0) { #ifdef USE_BPLUS - code = cm_BPlusDirLookup(&dirop, sp->searchNamep, &sp->fid); + code = cm_BPlusDirLookup(&dirop, sp->nsearchNamep, &sp->fid); if (code != EINVAL) usedBplus = 1; else @@ -847,18 +700,18 @@ long cm_ApplyDir(cm_scache_t *scp, cm_DirFuncp_t funcp, void *parmp, return code; } -int cm_NoneUpper(char *s) +int cm_NoneUpper(normchar_t *s) { - char c; + normchar_t c; while (c = *s++) if (c >= 'A' && c <= 'Z') return 0; return 1; } -int cm_NoneLower(char *s) +int cm_NoneLower(normchar_t *s) { - char c; + normchar_t c; while (c = *s++) if (c >= 'a' && c <= 'z') return 0; @@ -866,30 +719,30 @@ int cm_NoneLower(char *s) } long cm_LookupSearchProc(cm_scache_t *scp, cm_dirEntry_t *dep, void *rockp, - osi_hyper_t *offp) + osi_hyper_t *offp) { cm_lookupSearch_t *sp; int match; - char matchName[MAX_PATH]; + normchar_t matchName[MAX_PATH]; int looking_for_short_name = FALSE; sp = (cm_lookupSearch_t *) rockp; - cm_NormalizeUtf8String(dep->name, -1, matchName, sizeof(matchName)/sizeof(char)); + cm_FsStringToNormString(dep->name, -1, matchName, lengthof(matchName)); if (sp->caseFold) - match = cm_stricmp_utf8(matchName, sp->searchNamep); + match = cm_NormStrCmpI(matchName, sp->nsearchNamep); else - match = strcmp(matchName, sp->searchNamep); + match = cm_NormStrCmp(matchName, sp->nsearchNamep); if (match != 0 - && sp->hasTilde - && !cm_Is8Dot3(dep->name)) { + && sp->hasTilde + && !cm_Is8Dot3(matchName)) { - cm_Gen8Dot3Name(dep, matchName, NULL); + cm_Gen8Dot3NameInt(dep->name, &dep->fid, matchName, NULL); if (sp->caseFold) - match = cm_stricmp_utf8(matchName, sp->searchNamep); + match = cm_NormStrCmpI(matchName, sp->nsearchNamep); else - match = strcmp(matchName, sp->searchNamep); + match = cm_NormStrCmp(matchName, sp->nsearchNamep); looking_for_short_name = TRUE; } @@ -913,7 +766,7 @@ long cm_LookupSearchProc(cm_scache_t *scp, cm_dirEntry_t *dep, void *rockp, */ /* Exact matches are the best. */ - match = strcmp(matchName, sp->searchNamep); + match = cm_NormStrCmp(matchName, sp->nsearchNamep); if (match == 0) { sp->ExactFound = 1; cm_SetFid(&sp->fid, sp->fid.cell, sp->fid.volume, ntohl(dep->fid.vnode), ntohl(dep->fid.unique)); @@ -1024,15 +877,15 @@ long cm_ReadMountPoint(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp) long cm_FollowMountPoint(cm_scache_t *scp, cm_scache_t *dscp, cm_user_t *userp, cm_req_t *reqp, cm_scache_t **outScpp) { - char *cellNamep; - char *volNamep; + fschar_t *cellNamep = NULL; + fschar_t *volNamep = NULL; int tlen; - long code; - char *cp; - char *mpNamep; + afs_uint32 code; + fschar_t *cp; + fschar_t *mpNamep; cm_volume_t *volp = NULL; cm_cell_t *cellp; - char mtType; + fschar_t mtType; cm_fid_t tfid; size_t vnLength; int targetType; @@ -1049,25 +902,23 @@ long cm_FollowMountPoint(cm_scache_t *scp, cm_scache_t *dscp, cm_user_t *userp, mpNamep = scp->mountPointStringp; if (!mpNamep[0]) return CM_ERROR_NOSUCHPATH; - tlen = (int)strlen(scp->mountPointStringp); + tlen = cm_FsStrLen(scp->mountPointStringp); mtType = *scp->mountPointStringp; - cellNamep = malloc(tlen); - volNamep = malloc(tlen); - cp = strrchr(mpNamep, ':'); + cp = cm_FsStrChr(mpNamep, _FS(':')); if (cp) { /* cellular mount point */ - memset(cellNamep, 0, tlen); - strncpy(cellNamep, mpNamep+1, cp - mpNamep - 1); - strcpy(volNamep, cp+1); + cellNamep = (fschar_t *)malloc((cp - mpNamep) * sizeof(fschar_t)); + cm_FsStrCpyN(cellNamep, cp - mpNamep, mpNamep + 1, cp - mpNamep - 1); + volNamep = cm_FsStrDup(cp+1); + /* now look up the cell */ lock_ReleaseWrite(&scp->rw); cellp = cm_GetCell(cellNamep, CM_FLAG_CREATE); lock_ObtainWrite(&scp->rw); - } - else { + } else { /* normal mt pt */ - strcpy(volNamep, mpNamep+1); + volNamep = cm_FsStrDup(mpNamep + 1); cellp = cm_FindCellByID(scp->fid.cell, 0); } @@ -1077,11 +928,11 @@ long cm_FollowMountPoint(cm_scache_t *scp, cm_scache_t *dscp, cm_user_t *userp, goto done; } - vnLength = strlen(volNamep); - if (vnLength >= 8 && strcmp(volNamep + vnLength - 7, ".backup") == 0) + vnLength = cm_FsStrLen(volNamep); + if (vnLength >= 8 && cm_FsStrCmp(volNamep + vnLength - 7, ".backup") == 0) targetType = BACKVOL; else if (vnLength >= 10 - && strcmp(volNamep + vnLength - 9, ".readonly") == 0) + && cm_FsStrCmp(volNamep + vnLength - 9, ".readonly") == 0) targetType = ROVOL; else targetType = RWVOL; @@ -1153,12 +1004,14 @@ long cm_FollowMountPoint(cm_scache_t *scp, cm_scache_t *dscp, cm_user_t *userp, done: if (volp) cm_PutVolume(volp); - free(cellNamep); - free(volNamep); + if (cellNamep) + free(cellNamep); + if (volNamep) + free(volNamep); return code; } -long cm_LookupInternal(cm_scache_t *dscp, char *namep, long flags, cm_user_t *userp, +long cm_LookupInternal(cm_scache_t *dscp, clientchar_t *cnamep, long flags, cm_user_t *userp, cm_req_t *reqp, cm_scache_t **outpScpp) { long code; @@ -1167,20 +1020,25 @@ long cm_LookupInternal(cm_scache_t *dscp, char *namep, long flags, cm_user_t *us cm_scache_t *mountedScp; cm_lookupSearch_t rock; int getroot; + normchar_t *nnamep = NULL; + fschar_t *fnamep = NULL; memset(&rock, 0, sizeof(rock)); if (dscp->fid.vnode == 1 && dscp->fid.unique == 1 - && strcmp(namep, "..") == 0) { + && cm_ClientStrCmp(cnamep, _C("..")) == 0) { if (dscp->dotdotFid.volume == 0) return CM_ERROR_NOSUCHVOLUME; rock.fid = dscp->dotdotFid; goto haveFid; - } else if (strcmp(namep, ".") == 0) { + } else if (cm_ClientStrCmp(cnamep, _C(".")) == 0) { rock.fid = dscp->fid; goto haveFid; } + nnamep = cm_ClientStringToNormStringAlloc(cnamep, -1, NULL); + fnamep = cm_ClientStringToFsStringAlloc(cnamep, -1, NULL); + if (flags & CM_FLAG_NOMOUNTCHASE) { /* In this case, we should go and call cm_Dir* functions directly since the following cm_ApplyDir() function will @@ -1194,12 +1052,12 @@ long cm_LookupInternal(cm_scache_t *dscp, char *namep, long flags, cm_user_t *us code = cm_BeginDirOp(dscp, userp, reqp, CM_DIRLOCK_READ, &dirop); if (code == 0) { #ifdef USE_BPLUS - code = cm_BPlusDirLookup(&dirop, namep, &rock.fid); + code = cm_BPlusDirLookup(&dirop, nnamep, &rock.fid); if (code != EINVAL) usedBplus = 1; else #endif - code = cm_DirLookup(&dirop, namep, &rock.fid); + code = cm_DirLookup(&dirop, fnamep, &rock.fid); cm_EndDirOp(&dirop); } @@ -1225,13 +1083,14 @@ long cm_LookupInternal(cm_scache_t *dscp, char *namep, long flags, cm_user_t *us rock.fid.cell = dscp->fid.cell; rock.fid.volume = dscp->fid.volume; - rock.searchNamep = namep; + rock.searchNamep = fnamep; + rock.nsearchNamep = nnamep; rock.caseFold = (flags & CM_FLAG_CASEFOLD); - rock.hasTilde = ((strchr(namep, '~') != NULL) ? 1 : 0); + rock.hasTilde = ((cm_ClientStrChr(cnamep, '~') != NULL) ? 1 : 0); /* If NOMOUNTCHASE, bypass DNLC by passing NULL scp pointer */ code = cm_ApplyDir(dscp, cm_LookupSearchProc, &rock, NULL, userp, reqp, - (flags & CM_FLAG_NOMOUNTCHASE) ? NULL : &tscp); + (flags & CM_FLAG_NOMOUNTCHASE) ? NULL : &tscp); /* code == 0 means we fell off the end of the dir, while stopnow means * that we stopped early, probably because we found the entry we're @@ -1244,31 +1103,34 @@ long cm_LookupInternal(cm_scache_t *dscp, char *namep, long flags, cm_user_t *us */ if (code == CM_ERROR_NOTDIR) { if (flags & CM_FLAG_CHECKPATH) - return CM_ERROR_NOSUCHPATH; + code = CM_ERROR_NOSUCHPATH; else - return CM_ERROR_NOSUCHFILE; + code = CM_ERROR_NOSUCHFILE; } - return code; + goto done; } getroot = (dscp==cm_data.rootSCachep) ; if (!rock.found) { if (!cm_freelanceEnabled || !getroot) { if (flags & CM_FLAG_CHECKPATH) - return CM_ERROR_NOSUCHPATH; + code = CM_ERROR_NOSUCHPATH; else - return CM_ERROR_NOSUCHFILE; + code = CM_ERROR_NOSUCHFILE; + goto done; } - else if (!strchr(namep, '#') && !strchr(namep, '%') && - strcmp(namep, "srvsvc") && strcmp(namep, "wkssvc") && - strcmp(namep, "ipc$")) + else if (!cm_ClientStrChr(cnamep, '#') && + !cm_ClientStrChr(cnamep, '%') && + cm_ClientStrCmpI(cnamep, _C("srvsvc")) && + cm_ClientStrCmpI(cnamep, _C("wkssvc")) && + cm_ClientStrCmpI(cnamep, _C("ipc$"))) { /* nonexistent dir on freelance root, so add it */ - char fullname[200] = "."; + fschar_t fullname[200] = "."; int found = 0; - osi_Log1(afsd_logp,"cm_Lookup adding mount for non-existent directory: %s", - osi_LogSaveString(afsd_logp,namep)); + osi_Log1(afsd_logp,"cm_Lookup adding mount for non-existent directory: %S", + osi_LogSaveClientString(afsd_logp,cnamep)); /* * There is an ugly behavior where a share name "foo" will be searched @@ -1278,39 +1140,42 @@ long cm_LookupInternal(cm_scache_t *dscp, char *namep, long flags, cm_user_t *us */ code = -1; - if (namep[0] == '.') { - if (cm_GetCell_Gen(&namep[1], &fullname[1], CM_FLAG_CREATE)) { + if (cnamep[0] == '.') { + if (cm_GetCell_Gen(&fnamep[1], &fullname[1], CM_FLAG_CREATE)) { found = 1; if (!cm_FreelanceMountPointExists(fullname, 0)) - code = cm_FreelanceAddMount(fullname, &fullname[1], "root.cell.", 1, &rock.fid); - if ( cm_stricmp_utf8(&namep[1], &fullname[1]) && - !cm_FreelanceMountPointExists(namep, flags & CM_FLAG_DFS_REFERRAL ? 1 : 0) && - !cm_FreelanceSymlinkExists(namep, flags & CM_FLAG_DFS_REFERRAL ? 1 : 0)) - code = cm_FreelanceAddSymlink(namep, fullname, &rock.fid); + code = cm_FreelanceAddMount(fullname, &fullname[1], "root.cell.", + 1, &rock.fid); + if ( cm_FsStrCmpI(&fnamep[1], &fullname[1]) && + !cm_FreelanceMountPointExists(fnamep, flags & CM_FLAG_DFS_REFERRAL ? 1 : 0) && + !cm_FreelanceSymlinkExists(fnamep, flags & CM_FLAG_DFS_REFERRAL ? 1 : 0)) + code = cm_FreelanceAddSymlink(fnamep, fullname, &rock.fid); } } else { - if (cm_GetCell_Gen(namep, fullname, CM_FLAG_CREATE)) { + if (cm_GetCell_Gen(fnamep, fullname, CM_FLAG_CREATE)) { found = 1; if (!cm_FreelanceMountPointExists(fullname, 0)) code = cm_FreelanceAddMount(fullname, fullname, "root.cell.", 0, &rock.fid); - if ( cm_stricmp_utf8(namep, fullname) && - !cm_FreelanceMountPointExists(namep, flags & CM_FLAG_DFS_REFERRAL ? 1 : 0) && - !cm_FreelanceSymlinkExists(namep, flags & CM_FLAG_DFS_REFERRAL ? 1 : 0)) - code = cm_FreelanceAddSymlink(namep, fullname, &rock.fid); + if ( cm_FsStrCmpI(fnamep, fullname) && + !cm_FreelanceMountPointExists(fnamep, flags & CM_FLAG_DFS_REFERRAL ? 1 : 0) && + !cm_FreelanceSymlinkExists(fnamep, flags & CM_FLAG_DFS_REFERRAL ? 1 : 0)) + code = cm_FreelanceAddSymlink(fnamep, fullname, &rock.fid); } } if (!found || code < 0) { /* add mount point failed, so give up */ if (flags & CM_FLAG_CHECKPATH) - return CM_ERROR_NOSUCHPATH; + code = CM_ERROR_NOSUCHPATH; else - return CM_ERROR_NOSUCHFILE; + code = CM_ERROR_NOSUCHFILE; + goto done; } tscp = NULL; /* to force call of cm_GetSCache */ } else { if (flags & CM_FLAG_CHECKPATH) - return CM_ERROR_NOSUCHPATH; + code = CM_ERROR_NOSUCHPATH; else - return CM_ERROR_NOSUCHFILE; + code = CM_ERROR_NOSUCHFILE; + goto done; } } @@ -1320,8 +1185,8 @@ long cm_LookupInternal(cm_scache_t *dscp, char *namep, long flags, cm_user_t *us dnlcHit = 0; code = cm_GetSCache(&rock.fid, &tscp, userp, reqp); if (code) - return code; - } + goto done; + } /* tscp is now held */ lock_ObtainWrite(&tscp->rw); @@ -1330,7 +1195,7 @@ long cm_LookupInternal(cm_scache_t *dscp, char *namep, long flags, cm_user_t *us if (code) { lock_ReleaseWrite(&tscp->rw); cm_ReleaseSCache(tscp); - return code; + goto done; } cm_SyncOpDone(tscp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); /* tscp is now locked */ @@ -1343,12 +1208,12 @@ long cm_LookupInternal(cm_scache_t *dscp, char *namep, long flags, cm_user_t *us code = cm_ReadMountPoint(tscp, userp, reqp); if (code == 0) code = cm_FollowMountPoint(tscp, dscp, userp, reqp, - &mountedScp); + &mountedScp); lock_ReleaseWrite(&tscp->rw); cm_ReleaseSCache(tscp); - if (code) { - return code; - } + if (code) + goto done; + tscp = mountedScp; } else { @@ -1363,26 +1228,39 @@ long cm_LookupInternal(cm_scache_t *dscp, char *namep, long flags, cm_user_t *us /* lock the directory entry to prevent racing callback revokes */ lock_ObtainRead(&dscp->rw); if ( dscp->cbServerp != NULL && dscp->cbExpires > 0 ) { - /* Note: namep is a normalized name */ - cm_dnlcEnter(dscp, namep, tscp); + /* TODO: reuse nnamep from above */ + if (nnamep) + free(nnamep); + nnamep = cm_ClientStringToNormStringAlloc(cnamep, -1, NULL); + cm_dnlcEnter(dscp, nnamep, tscp); } lock_ReleaseRead(&dscp->rw); } /* and return */ - return 0; + done: + if (fnamep) { + free (fnamep); + fnamep = NULL; + } + if (nnamep) { + free (nnamep); + nnamep = NULL; + } + + return code; } -int cm_ExpandSysName(char *inp, char *outp, long outSize, unsigned int index) +int cm_ExpandSysName(clientchar_t *inp, clientchar_t *outp, long outSizeCch, unsigned int index) { - char *tp; + clientchar_t *tp; int prefixCount; - tp = strrchr(inp, '@'); + tp = cm_ClientStrRChr(inp, '@'); if (tp == NULL) return 0; /* no @sys */ - if (strcmp(tp, "@sys") != 0) + if (cm_ClientStrCmp(tp, _C("@sys")) != 0) return 0; /* no @sys */ /* caller just wants to know if this is a valid @sys type of name */ @@ -1395,21 +1273,22 @@ int cm_ExpandSysName(char *inp, char *outp, long outSize, unsigned int index) /* otherwise generate the properly expanded @sys name */ prefixCount = (int)(tp - inp); - strncpy(outp, inp, prefixCount); /* copy out "a." from "a.@sys" */ + cm_ClientStrCpyN(outp, outSizeCch, inp, prefixCount); /* copy out "a." from "a.@sys" */ outp[prefixCount] = 0; /* null terminate the "a." */ - strcat(outp, cm_sysNameList[index]);/* append i386_nt40 */ + cm_ClientStrCat(outp, outSizeCch, cm_sysNameList[index]);/* append i386_nt40 */ return 1; } -long cm_EvaluateVolumeReference(char * namep, long flags, cm_user_t * userp, +long cm_EvaluateVolumeReference(clientchar_t * namep, long flags, cm_user_t * userp, cm_req_t *reqp, cm_scache_t ** outpScpp) { - long code = 0; - char cellName[CELL_MAXNAMELEN]; - char volumeName[VL_MAXNAMELEN]; + afs_uint32 code = 0; + fschar_t cellName[CELL_MAXNAMELEN]; + fschar_t volumeName[VL_MAXNAMELEN]; size_t len; - char * cp; - char * tp; + fschar_t * cp; + fschar_t * tp; + fschar_t * fnamep = NULL; cm_cell_t * cellp = NULL; cm_volume_t * volp = NULL; @@ -1418,10 +1297,10 @@ long cm_EvaluateVolumeReference(char * namep, long flags, cm_user_t * userp, int volType; int mountType = RWVOL; - osi_Log1(afsd_logp, "cm_EvaluateVolumeReference for string [%s]", - osi_LogSaveString(afsd_logp, namep)); + osi_Log1(afsd_logp, "cm_EvaluateVolumeReference for string [%S]", + osi_LogSaveClientString(afsd_logp, namep)); - if (strnicmp(namep, CM_PREFIX_VOL, CM_PREFIX_VOL_CCH) != 0) { + if (cm_ClientStrCmpNI(namep, _C(CM_PREFIX_VOL), CM_PREFIX_VOL_CCH) != 0) { goto _exit_invalid_path; } @@ -1433,39 +1312,38 @@ long cm_EvaluateVolumeReference(char * namep, long flags, cm_user_t * userp, */ - cp = namep + CM_PREFIX_VOL_CCH; /* cp points to cell name, hopefully */ - tp = strchr(cp, '%'); + fnamep = cm_ClientStringToFsStringAlloc(namep, cm_ClientStrLen(namep), NULL); + cp = fnamep + CM_PREFIX_VOL_CCH; /* cp points to cell name, hopefully */ + tp = cm_FsStrChr(cp, '%'); if (tp == NULL) - tp = strchr(cp, '#'); + tp = cm_FsStrChr(cp, '#'); if (tp == NULL || (len = tp - cp) == 0 || len > CELL_MAXNAMELEN) goto _exit_invalid_path; - strncpy(cellName, cp, len); - cellName[len] = '\0'; + cm_FsStrCpyN(cellName, lengthof(cellName), cp, len); if (*tp == '#') mountType = ROVOL; cp = tp+1; /* cp now points to volume, supposedly */ - strncpy(volumeName, cp, VL_MAXNAMELEN-1); - volumeName[VL_MAXNAMELEN - 1] = 0; + cm_FsStrCpy(volumeName, lengthof(volumeName), cp); /* OK, now we have the cell and the volume */ osi_Log2(afsd_logp, " Found cell [%s] and volume [%s]", - osi_LogSaveString(afsd_logp, cellName), - osi_LogSaveString(afsd_logp, volumeName)); + osi_LogSaveFsString(afsd_logp, cellName), + osi_LogSaveFsString(afsd_logp, volumeName)); cellp = cm_GetCell(cellName, CM_FLAG_CREATE); if (cellp == NULL) { goto _exit_invalid_path; } - len = strlen(volumeName); - if (len >= 8 && strcmp(volumeName + len - 7, ".backup") == 0) + len = cm_FsStrLen(volumeName); + if (len >= 8 && cm_FsStrCmp(volumeName + len - 7, ".backup") == 0) volType = BACKVOL; else if (len >= 10 && - strcmp(volumeName + len - 9, ".readonly") == 0) + cm_FsStrCmp(volumeName + len - 9, ".readonly") == 0) volType = ROVOL; else volType = RWVOL; @@ -1493,7 +1371,10 @@ long cm_EvaluateVolumeReference(char * namep, long flags, cm_user_t * userp, code = cm_GetSCache(&fid, outpScpp, userp, reqp); - _exit_cleanup: + _exit_cleanup: + if (fnamep) + free(fnamep); + if (volp) cm_PutVolume(volp); @@ -1508,15 +1389,15 @@ long cm_EvaluateVolumeReference(char * namep, long flags, cm_user_t * userp, } #ifdef DEBUG_REFCOUNT -long cm_LookupDbg(cm_scache_t *dscp, char *namep, long flags, cm_user_t *userp, +long cm_LookupDbg(cm_scache_t *dscp, clientchar_t *namep, long flags, cm_user_t *userp, cm_req_t *reqp, cm_scache_t **outpScpp, char * file, long line) #else -long cm_Lookup(cm_scache_t *dscp, char *namep, long flags, cm_user_t *userp, +long cm_Lookup(cm_scache_t *dscp, clientchar_t *namep, long flags, cm_user_t *userp, cm_req_t *reqp, cm_scache_t **outpScpp) #endif { long code; - char tname[AFSPATHMAX]; + clientchar_t tname[AFSPATHMAX]; int sysNameIndex = 0; cm_scache_t *scp = NULL; @@ -1525,7 +1406,7 @@ long cm_Lookup(cm_scache_t *dscp, char *namep, long flags, cm_user_t *userp, osi_Log2(afsd_logp, "cm_Lookup dscp 0x%p ref %d", dscp, dscp->refCount); #endif - if ( cm_stricmp_utf8N(namep,SMB_IOCTL_FILENAME_NOSLASH) == 0 ) { + if ( cm_ClientStrCmpI(namep,_C(SMB_IOCTL_FILENAME_NOSLASH)) == 0 ) { if (flags & CM_FLAG_CHECKPATH) return CM_ERROR_NOSUCHPATH; else @@ -1533,13 +1414,13 @@ long cm_Lookup(cm_scache_t *dscp, char *namep, long flags, cm_user_t *userp, } if (dscp == cm_data.rootSCachep && - strnicmp(namep, CM_PREFIX_VOL, CM_PREFIX_VOL_CCH) == 0) { + cm_ClientStrCmpNI(namep, _C(CM_PREFIX_VOL), CM_PREFIX_VOL_CCH) == 0) { return cm_EvaluateVolumeReference(namep, flags, userp, reqp, outpScpp); } if (cm_ExpandSysName(namep, NULL, 0, 0) > 0) { for ( sysNameIndex = 0; sysNameIndex < MAXNUMSYSNAMES; sysNameIndex++) { - code = cm_ExpandSysName(namep, tname, sizeof(tname), sysNameIndex); + code = cm_ExpandSysName(namep, tname, lengthof(tname), sysNameIndex); if (code > 0) { code = cm_LookupInternal(dscp, tname, flags, userp, reqp, &scp); #ifdef DEBUG_REFCOUNT @@ -1589,18 +1470,20 @@ long cm_Lookup(cm_scache_t *dscp, char *namep, long flags, cm_user_t *userp, \param[in] dscp cm_scache_t pointing at the directory containing the name to be unlinked. - \param[in] namep Non-normalized name to be unlinked. This is the + \param[in] fnamep Original name to be unlinked. This is the name that will be passed into the RXAFS_RemoveFile() call. + This parameter is optional. If not provided, the value will + be looked up. - \param[in] normalizedName Normalized name to be unlinked. This name - will be used to update the local directory caches. + \param[in] came Client name to be unlinked. This name will be used + to update the local directory caches. \param[in] userp cm_user_t for the request. \param[in] reqp Request tracker. */ -long cm_Unlink(cm_scache_t *dscp, char *namep, char * normalizedName, +long cm_Unlink(cm_scache_t *dscp, fschar_t *fnamep, clientchar_t * cnamep, cm_user_t *userp, cm_req_t *reqp) { long code; @@ -1612,16 +1495,32 @@ long cm_Unlink(cm_scache_t *dscp, char *namep, char * normalizedName, struct rx_connection * callp; cm_dirOp_t dirop; cm_scache_t *scp = NULL; + int free_fnamep = FALSE; + + if (fnamep == NULL) { + code = -1; +#ifdef USE_BPLUS + code = cm_BeginDirOp(dscp, userp, reqp, CM_DIRLOCK_READ, &dirop); + if (code == 0) { + code = cm_BPlusDirLookupOriginalName(&dirop, cnamep, &fnamep); + if (code == 0) + free_fnamep = TRUE; + cm_EndDirOp(&dirop); + } +#endif + if (code) + goto done; + } #ifdef AFS_FREELANCE_CLIENT if (cm_freelanceEnabled && dscp == cm_data.rootSCachep) { /* deleting a mount point from the root dir. */ - code = cm_FreelanceRemoveMount(namep); - return code; + code = cm_FreelanceRemoveMount(fnamep); + goto done; } #endif - code = cm_Lookup(dscp, namep, CM_FLAG_NOMOUNTCHASE, userp, reqp, &scp); + code = cm_Lookup(dscp, cnamep, CM_FLAG_NOMOUNTCHASE, userp, reqp, &scp); /* make sure we don't screw up the dir status during the merge */ code = cm_BeginDirOp(dscp, userp, reqp, CM_DIRLOCK_NONE, &dirop); @@ -1632,7 +1531,7 @@ long cm_Unlink(cm_scache_t *dscp, char *namep, char * normalizedName, lock_ReleaseWrite(&dscp->rw); if (code) { cm_EndDirOp(&dirop); - return code; + goto done; } /* make the RPC */ @@ -1643,12 +1542,12 @@ long cm_Unlink(cm_scache_t *dscp, char *namep, char * normalizedName, osi_Log1(afsd_logp, "CALL RemoveFile scp 0x%p", dscp); do { code = cm_ConnFromFID(&dscp->fid, userp, reqp, &connp); - if (code) + if (code) continue; callp = cm_GetRxConn(connp); - code = RXAFS_RemoveFile(callp, &afsFid, namep, - &newDirStatus, &volSync); + code = RXAFS_RemoveFile(callp, &afsFid, fnamep, + &newDirStatus, &volSync); rx_PutConnection(callp); } while (cm_Analyze(connp, userp, reqp, &dscp->fid, &volSync, NULL, NULL, code)); @@ -1664,7 +1563,7 @@ long cm_Unlink(cm_scache_t *dscp, char *namep, char * normalizedName, dirop.lockType = CM_DIRLOCK_WRITE; } lock_ObtainWrite(&dscp->rw); - cm_dnlcRemove(dscp, normalizedName); + cm_dnlcRemove(dscp, cnamep); cm_SyncOpDone(dscp, NULL, sflags); if (code == 0) { cm_MergeStatus(NULL, dscp, &newDirStatus, &volSync, userp, CM_MERGEFLAG_DIROP); @@ -1677,10 +1576,10 @@ long cm_Unlink(cm_scache_t *dscp, char *namep, char * normalizedName, } lock_ReleaseWrite(&dscp->rw); - if (code == 0 && cm_CheckDirOpForSingleChange(&dirop) && normalizedName) { - cm_DirDeleteEntry(&dirop, namep); + if (code == 0 && cm_CheckDirOpForSingleChange(&dirop) && cnamep) { + cm_DirDeleteEntry(&dirop, fnamep); #ifdef USE_BPLUS - cm_BPlusDirDeleteEntry(&dirop, normalizedName); + cm_BPlusDirDeleteEntry(&dirop, cnamep); #endif } cm_EndDirOp(&dirop); @@ -1694,6 +1593,10 @@ long cm_Unlink(cm_scache_t *dscp, char *namep, char * normalizedName, } } + done: + if (free_fnamep) + free(fnamep); + return code; } @@ -1765,13 +1668,13 @@ long cm_HandleLink(cm_scache_t *linkScp, cm_user_t *userp, cm_req_t *reqp) * other than the directory containing the symbolic link, then the new root is * returned in *newRootScpp, otherwise a null is returned there. */ -long cm_AssembleLink(cm_scache_t *linkScp, char *pathSuffixp, - cm_scache_t **newRootScpp, cm_space_t **newSpaceBufferp, - cm_user_t *userp, cm_req_t *reqp) +long cm_AssembleLink(cm_scache_t *linkScp, fschar_t *pathSuffixp, + cm_scache_t **newRootScpp, cm_space_t **newSpaceBufferp, + cm_user_t *userp, cm_req_t *reqp) { long code = 0; long len; - char *linkp; + fschar_t *linkp; cm_space_t *tsp; *newRootScpp = NULL; @@ -1786,17 +1689,17 @@ long cm_AssembleLink(cm_scache_t *linkScp, char *pathSuffixp, * bigger than max path length, so we don't really have to worry about * being a little conservative here. */ - if (strlen(linkScp->mountPointStringp) + strlen(pathSuffixp) + 2 - >= CM_UTILS_SPACESIZE) { + if (cm_FsStrLen(linkScp->mountPointStringp) + cm_FsStrLen(pathSuffixp) + 2 + >= CM_UTILS_SPACESIZE) { code = CM_ERROR_TOOBIG; - goto done; - } + goto done; + } tsp = cm_GetSpace(); linkp = linkScp->mountPointStringp; if (strncmp(linkp, cm_mountRoot, cm_mountRootLen) == 0) { if (strlen(linkp) > cm_mountRootLen) - strcpy(tsp->data, linkp+cm_mountRootLen+1); + StringCbCopyA((char *) tsp->data, sizeof(tsp->data), linkp+cm_mountRootLen+1); else tsp->data[0] = 0; *newRootScpp = cm_data.rootSCachep; @@ -1808,7 +1711,7 @@ long cm_AssembleLink(cm_scache_t *linkScp, char *pathSuffixp, if (strnicmp(p, "all", 3) == 0) p += 4; - strcpy(tsp->data, p); + StringCbCopyA(tsp->data, sizeof(tsp->data), p); for (p = tsp->data; *p; p++) { if (*p == '\\') *p = '/'; @@ -1817,20 +1720,20 @@ long cm_AssembleLink(cm_scache_t *linkScp, char *pathSuffixp, cm_HoldSCache(cm_data.rootSCachep); } else { linkScp->fileType = CM_SCACHETYPE_DFSLINK; - strcpy(tsp->data, linkp); + StringCchCopyA(tsp->data,lengthof(tsp->data), linkp); code = CM_ERROR_PATH_NOT_COVERED; } } else if ( linkScp->fileType == CM_SCACHETYPE_DFSLINK || !strnicmp(linkp, "msdfs:", (len = (long)strlen("msdfs:"))) ) { linkScp->fileType = CM_SCACHETYPE_DFSLINK; - strcpy(tsp->data, linkp); + StringCchCopyA(tsp->data,lengthof(tsp->data), linkp); code = CM_ERROR_PATH_NOT_COVERED; } else if (*linkp == '\\' || *linkp == '/') { #if 0 /* formerly, this was considered to be from the AFS root, * but this seems to create problems. instead, we will just * reject the link */ - strcpy(tsp->data, linkp+1); + StringCchCopyA(tsp->data,lengthof(tsp->data), linkp+1); *newRootScpp = cm_data.rootSCachep; cm_HoldSCache(cm_data.rootSCachep); #else @@ -1838,45 +1741,51 @@ long cm_AssembleLink(cm_scache_t *linkScp, char *pathSuffixp, * the user can see what the link points to */ linkScp->fileType = CM_SCACHETYPE_INVALID; - strcpy(tsp->data, linkp); + StringCchCopyA(tsp->data,lengthof(tsp->data), linkp); code = CM_ERROR_NOSUCHPATH; #endif } else { /* a relative link */ - strcpy(tsp->data, linkp); + StringCchCopyA(tsp->data,lengthof(tsp->data), linkp); } if (pathSuffixp[0] != 0) { /* if suffix string is non-null */ - strcat(tsp->data, "\\"); - strcat(tsp->data, pathSuffixp); + StringCchCatA(tsp->data,lengthof(tsp->data), "\\"); + StringCchCatA(tsp->data,lengthof(tsp->data), pathSuffixp); } - if (code == 0) + if (code == 0) { + clientchar_t * cpath = cm_FsStringToClientStringAlloc(tsp->data, -1, NULL); + cm_ClientStrCpy(tsp->wdata, lengthof(tsp->wdata), cpath); + free(cpath); *newSpaceBufferp = tsp; - else { + } else { cm_FreeSpace(tsp); - if (code == CM_ERROR_PATH_NOT_COVERED && reqp->tidPathp && reqp->relPathp) + if (code == CM_ERROR_PATH_NOT_COVERED && reqp->tidPathp && reqp->relPathp) { cm_VolStatus_Notify_DFS_Mapping(linkScp, reqp->tidPathp, reqp->relPathp); + } } - done: + done: lock_ReleaseWrite(&linkScp->rw); return code; } #ifdef DEBUG_REFCOUNT -long cm_NameIDbg(cm_scache_t *rootSCachep, char *pathp, long flags, - cm_user_t *userp, char *tidPathp, cm_req_t *reqp, cm_scache_t **outScpp, - char * file, long line) +long cm_NameIDbg(cm_scache_t *rootSCachep, clientchar_t *pathp, long flags, + cm_user_t *userp, clientchar_t *tidPathp, cm_req_t *reqp, + cm_scache_t **outScpp, + char * file, long line) #else -long cm_NameI(cm_scache_t *rootSCachep, char *pathp, long flags, - cm_user_t *userp, char *tidPathp, cm_req_t *reqp, cm_scache_t **outScpp) +long cm_NameI(cm_scache_t *rootSCachep, clientchar_t *pathp, long flags, + cm_user_t *userp, clientchar_t *tidPathp, + cm_req_t *reqp, cm_scache_t **outScpp) #endif { long code; - char *tp; /* ptr moving through input buffer */ - char tc; /* temp char */ + clientchar_t *tp; /* ptr moving through input buffer */ + clientchar_t tc; /* temp char */ int haveComponent; /* has new component started? */ - char component[AFSPATHMAX]; /* this is the new component */ - char *cp; /* component name being assembled */ + clientchar_t component[AFSPATHMAX]; /* this is the new component */ + clientchar_t *cp; /* component name being assembled */ cm_scache_t *tscp; /* current location in the hierarchy */ cm_scache_t *nscp; /* next dude down */ cm_scache_t *dirScp; /* last dir we searched */ @@ -1885,7 +1794,7 @@ long cm_NameI(cm_scache_t *rootSCachep, char *pathp, long flags, cm_space_t *psp; /* space for current path, if we've hit * any symlinks */ cm_space_t *tempsp; /* temp vbl */ - char *restp; /* rest of the pathname to interpret */ + clientchar_t *restp; /* rest of the pathname to interpret */ int symlinkCount; /* count of # of symlinks traversed */ int extraFlag; /* avoid chasing mt pts for dir cmd */ int phase = 1; /* 1 = tidPathp, 2 = pathp */ @@ -1896,9 +1805,9 @@ long cm_NameI(cm_scache_t *rootSCachep, char *pathp, long flags, #ifdef DEBUG_REFCOUNT afsi_log("%s:%d cm_NameI rootscp 0x%p ref %d", file, line, rootSCachep, rootSCachep->refCount); - osi_Log4(afsd_logp,"cm_NameI rootscp 0x%p path %s tidpath %s flags 0x%x", - rootSCachep, pathp ? pathp : "", tidPathp ? tidPathp : "", - flags); + osi_Log4(afsd_logp,"cm_NameI rootscp 0x%p path %S tidpath %S flags 0x%x", + rootSCachep, pathp ? pathp : "", tidPathp ? tidPathp : "", + flags); #endif tp = tidPathp; @@ -1907,7 +1816,7 @@ long cm_NameI(cm_scache_t *rootSCachep, char *pathp, long flags, phase = 2; } if (tp == NULL) { - tp = ""; + tp = _C(""); } haveComponent = 0; psp = NULL; @@ -1954,16 +1863,18 @@ long cm_NameI(cm_scache_t *rootSCachep, char *pathp, long flags, if ((flags & CM_FLAG_DIRSEARCH) && tc == 0) extraFlag = CM_FLAG_NOMOUNTCHASE; code = cm_Lookup(tscp, component, - flags | extraFlag, - userp, reqp, &nscp); + flags | extraFlag, + userp, reqp, &nscp); if (code == 0) { - if (!strcmp(component,"..") || !strcmp(component,".")) { + if (!cm_ClientStrCmp(component,_C("..")) || + !cm_ClientStrCmp(component,_C("."))) { /* - * roll back the fid list until we find the fid - * that matches where we are now. Its not necessarily - * one or two fids because they might have been - * symlinks or mount points or both that were crossed. + * roll back the fid list until we find the + * fid that matches where we are now. Its not + * necessarily one or two fids because they + * might have been symlinks or mount points or + * both that were crossed. */ for ( i=fid_count-1; i>=0; i--) { if (!cm_FidCmp(&nscp->fid, &fids[i])) @@ -1993,8 +1904,7 @@ long cm_NameI(cm_scache_t *rootSCachep, char *pathp, long flags, if (psp) cm_FreeSpace(psp); if ((code == CM_ERROR_NOSUCHFILE || code == CM_ERROR_BPLUS_NOMATCH) && - tscp->fileType == CM_SCACHETYPE_SYMLINK) - { + tscp->fileType == CM_SCACHETYPE_SYMLINK) { osi_Log0(afsd_logp,"cm_NameI code CM_ERROR_NOSUCHPATH"); return CM_ERROR_NOSUCHPATH; } else { @@ -2018,8 +1928,8 @@ long cm_NameI(cm_scache_t *rootSCachep, char *pathp, long flags, break; } - /* now, if tscp is a symlink, we should follow - * it and assemble the path again. + /* now, if tscp is a symlink, we should follow it and + * assemble the path again. */ lock_ObtainWrite(&tscp->rw); code = cm_SyncOp(tscp, NULL, userp, reqp, 0, @@ -2053,10 +1963,18 @@ long cm_NameI(cm_scache_t *rootSCachep, char *pathp, long flags, return CM_ERROR_TOO_MANY_SYMLINKS; } if (tc == 0) - restp = ""; + restp = _C(""); else restp = tp; - code = cm_AssembleLink(tscp, restp, &linkScp, &tempsp, userp, reqp); + + { + fschar_t * frestp; + + /* TODO: make this better */ + frestp = cm_ClientStringToFsStringAlloc(restp, -1, NULL); + code = cm_AssembleLink(tscp, frestp, &linkScp, &tempsp, userp, reqp); + free(frestp); + } if (code == 0 && linkScp != NULL) { if (linkScp == cm_data.rootSCachep) @@ -2098,7 +2016,7 @@ long cm_NameI(cm_scache_t *rootSCachep, char *pathp, long flags, if (psp) cm_FreeSpace(psp); psp = tempsp; - tp = psp->data; + tp = psp->wdata; cm_ReleaseSCache(tscp); tscp = linkScp; linkScp = NULL; @@ -2196,9 +2114,9 @@ long cm_EvaluateSymLink(cm_scache_t *dscp, cm_scache_t *linkScp, cm_HoldSCache(dscp); } - code = cm_NameI(newRootScp, spacep->data, - CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW | CM_FLAG_DIRSEARCH, - userp, NULL, reqp, outScpp); + code = cm_NameI(newRootScp, spacep->wdata, + CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW | CM_FLAG_DIRSEARCH, + userp, NULL, reqp, outScpp); if (code == CM_ERROR_NOSUCHFILE || code == CM_ERROR_BPLUS_NOMATCH) code = CM_ERROR_NOSUCHPATH; @@ -2674,7 +2592,7 @@ long cm_SetAttr(cm_scache_t *scp, cm_attr_t *attrp, cm_user_t *userp, return code; } -long cm_Create(cm_scache_t *dscp, char *namep, long flags, cm_attr_t *attrp, +long cm_Create(cm_scache_t *dscp, clientchar_t *cnamep, long flags, cm_attr_t *attrp, cm_scache_t **scpp, cm_user_t *userp, cm_req_t *reqp) { cm_conn_t *connp; @@ -2692,11 +2610,12 @@ long cm_Create(cm_scache_t *dscp, char *namep, long flags, cm_attr_t *attrp, AFSVolSync volSync; struct rx_connection * callp; cm_dirOp_t dirop; + fschar_t * fnamep = NULL; /* can't create names with @sys in them; must expand it manually first. * return "invalid request" if they try. */ - if (cm_ExpandSysName(namep, NULL, 0, 0)) { + if (cm_ExpandSysName(cnamep, NULL, 0, 0)) { return CM_ERROR_ATSYS; } @@ -2728,6 +2647,8 @@ long cm_Create(cm_scache_t *dscp, char *namep, long flags, cm_attr_t *attrp, } didEnd = 0; + fnamep = cm_ClientStringToFsStringAlloc(cnamep, -1, NULL); + cm_StatusFromAttr(&inStatus, NULL, attrp); /* try the RPC now */ @@ -2742,7 +2663,7 @@ long cm_Create(cm_scache_t *dscp, char *namep, long flags, cm_attr_t *attrp, dirAFSFid.Unique = dscp->fid.unique; callp = cm_GetRxConn(connp); - code = RXAFS_CreateFile(connp->callp, &dirAFSFid, namep, + code = RXAFS_CreateFile(connp->callp, &dirAFSFid, fnamep, &inStatus, &newAFSFid, &newFileStatus, &updatedDirStatus, &newFileCallback, &volSync); @@ -2781,9 +2702,9 @@ long cm_Create(cm_scache_t *dscp, char *namep, long flags, cm_attr_t *attrp, scp->creator = userp; /* remember who created it */ if (!cm_HaveCallback(scp)) { cm_MergeStatus(dscp, scp, &newFileStatus, &volSync, - userp, 0); + userp, 0); cm_EndCallbackGrantingCall(scp, &cbReq, - &newFileCallback, 0); + &newFileCallback, 0); didEnd = 1; } lock_ReleaseWrite(&scp->rw); @@ -2796,13 +2717,16 @@ long cm_Create(cm_scache_t *dscp, char *namep, long flags, cm_attr_t *attrp, cm_EndCallbackGrantingCall(NULL, &cbReq, NULL, 0); if (scp && cm_CheckDirOpForSingleChange(&dirop)) { - cm_DirCreateEntry(&dirop, namep, &newFid); + cm_DirCreateEntry(&dirop, fnamep, &newFid); #ifdef USE_BPLUS - cm_BPlusDirCreateEntry(&dirop, namep, &newFid); + cm_BPlusDirCreateEntry(&dirop, cnamep, &newFid); #endif } cm_EndDirOp(&dirop); + if (fnamep) + free(fnamep); + return code; } @@ -2829,7 +2753,7 @@ long cm_FSync(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp) return code; } -long cm_MakeDir(cm_scache_t *dscp, char *namep, long flags, cm_attr_t *attrp, +long cm_MakeDir(cm_scache_t *dscp, clientchar_t *cnamep, long flags, cm_attr_t *attrp, cm_user_t *userp, cm_req_t *reqp) { cm_conn_t *connp; @@ -2847,11 +2771,12 @@ long cm_MakeDir(cm_scache_t *dscp, char *namep, long flags, cm_attr_t *attrp, AFSVolSync volSync; struct rx_connection * callp; cm_dirOp_t dirop; + fschar_t * fnamep = NULL; /* can't create names with @sys in them; must expand it manually first. * return "invalid request" if they try. */ - if (cm_ExpandSysName(namep, NULL, 0, 0)) { + if (cm_ExpandSysName(cnamep, NULL, 0, 0)) { return CM_ERROR_ATSYS; } @@ -2883,6 +2808,7 @@ long cm_MakeDir(cm_scache_t *dscp, char *namep, long flags, cm_attr_t *attrp, } didEnd = 0; + fnamep = cm_ClientStringToFsStringAlloc(cnamep, -1, NULL); cm_StatusFromAttr(&inStatus, NULL, attrp); /* try the RPC now */ @@ -2897,14 +2823,14 @@ long cm_MakeDir(cm_scache_t *dscp, char *namep, long flags, cm_attr_t *attrp, dirAFSFid.Unique = dscp->fid.unique; callp = cm_GetRxConn(connp); - code = RXAFS_MakeDir(connp->callp, &dirAFSFid, namep, + code = RXAFS_MakeDir(connp->callp, &dirAFSFid, fnamep, &inStatus, &newAFSFid, &newDirStatus, &updatedDirStatus, &newDirCallback, &volSync); rx_PutConnection(callp); } while (cm_Analyze(connp, userp, reqp, - &dscp->fid, &volSync, NULL, &cbReq, code)); + &dscp->fid, &volSync, NULL, &cbReq, code)); code = cm_MapRPCError(code, reqp); if (code) @@ -2950,18 +2876,20 @@ long cm_MakeDir(cm_scache_t *dscp, char *namep, long flags, cm_attr_t *attrp, cm_EndCallbackGrantingCall(NULL, &cbReq, NULL, 0); if (scp && cm_CheckDirOpForSingleChange(&dirop)) { - cm_DirCreateEntry(&dirop, namep, &newFid); + cm_DirCreateEntry(&dirop, fnamep, &newFid); #ifdef USE_BPLUS - cm_BPlusDirCreateEntry(&dirop, namep, &newFid); + cm_BPlusDirCreateEntry(&dirop, cnamep, &newFid); #endif } cm_EndDirOp(&dirop); + free(fnamep); + /* and return error code */ return code; } -long cm_Link(cm_scache_t *dscp, char *namep, cm_scache_t *sscp, long flags, +long cm_Link(cm_scache_t *dscp, clientchar_t *cnamep, cm_scache_t *sscp, long flags, cm_user_t *userp, cm_req_t *reqp) { cm_conn_t *connp; @@ -2973,6 +2901,7 @@ long cm_Link(cm_scache_t *dscp, char *namep, cm_scache_t *sscp, long flags, AFSVolSync volSync; struct rx_connection * callp; cm_dirOp_t dirop; + fschar_t * fnamep = NULL; if (dscp->fid.cell != sscp->fid.cell || dscp->fid.volume != sscp->fid.volume) { @@ -2989,6 +2918,8 @@ long cm_Link(cm_scache_t *dscp, char *namep, cm_scache_t *sscp, long flags, if (code) return code; + fnamep = cm_ClientStringToFsStringAlloc(cnamep, -1, NULL); + /* try the RPC now */ osi_Log1(afsd_logp, "CALL Link scp 0x%p", dscp); do { @@ -3004,7 +2935,7 @@ long cm_Link(cm_scache_t *dscp, char *namep, cm_scache_t *sscp, long flags, existingAFSFid.Unique = sscp->fid.unique; callp = cm_GetRxConn(connp); - code = RXAFS_Link(callp, &dirAFSFid, namep, &existingAFSFid, + code = RXAFS_Link(callp, &dirAFSFid, fnamep, &existingAFSFid, &newLinkStatus, &updatedDirStatus, &volSync); rx_PutConnection(callp); osi_Log1(afsd_logp," RXAFS_Link returns 0x%x", code); @@ -3032,18 +2963,20 @@ long cm_Link(cm_scache_t *dscp, char *namep, cm_scache_t *sscp, long flags, if (code == 0) { if (cm_CheckDirOpForSingleChange(&dirop)) { - cm_DirCreateEntry(&dirop, namep, &sscp->fid); + cm_DirCreateEntry(&dirop, fnamep, &sscp->fid); #ifdef USE_BPLUS - cm_BPlusDirCreateEntry(&dirop, namep, &sscp->fid); + cm_BPlusDirCreateEntry(&dirop, cnamep, &sscp->fid); #endif } } cm_EndDirOp(&dirop); + free(fnamep); + return code; } -long cm_SymLink(cm_scache_t *dscp, char *namep, char *contentsp, long flags, +long cm_SymLink(cm_scache_t *dscp, clientchar_t *cnamep, fschar_t *contentsp, long flags, cm_attr_t *attrp, cm_user_t *userp, cm_req_t *reqp) { cm_conn_t *connp; @@ -3058,6 +2991,7 @@ long cm_SymLink(cm_scache_t *dscp, char *namep, char *contentsp, long flags, AFSVolSync volSync; struct rx_connection * callp; cm_dirOp_t dirop; + fschar_t *fnamep = NULL; /* before starting the RPC, mark that we're changing the directory data, * so that someone who does a chmod on the dir will wait until our @@ -3073,6 +3007,8 @@ long cm_SymLink(cm_scache_t *dscp, char *namep, char *contentsp, long flags, return code; } + fnamep = cm_ClientStringToFsStringAlloc(cnamep, -1, NULL); + cm_StatusFromAttr(&inStatus, NULL, attrp); /* try the RPC now */ @@ -3087,7 +3023,7 @@ long cm_SymLink(cm_scache_t *dscp, char *namep, char *contentsp, long flags, dirAFSFid.Unique = dscp->fid.unique; callp = cm_GetRxConn(connp); - code = RXAFS_Symlink(callp, &dirAFSFid, namep, contentsp, + code = RXAFS_Symlink(callp, &dirAFSFid, fnamep, contentsp, &inStatus, &newAFSFid, &newLinkStatus, &updatedDirStatus, &volSync); rx_PutConnection(callp); @@ -3116,9 +3052,9 @@ long cm_SymLink(cm_scache_t *dscp, char *namep, char *contentsp, long flags, if (cm_CheckDirOpForSingleChange(&dirop)) { cm_SetFid(&newFid, dscp->fid.cell, dscp->fid.volume, newAFSFid.Vnode, newAFSFid.Unique); - cm_DirCreateEntry(&dirop, namep, &newFid); + cm_DirCreateEntry(&dirop, fnamep, &newFid); #ifdef USE_BPLUS - cm_BPlusDirCreateEntry(&dirop, namep, &newFid); + cm_BPlusDirCreateEntry(&dirop, cnamep, &newFid); #endif } } @@ -3142,6 +3078,8 @@ long cm_SymLink(cm_scache_t *dscp, char *namep, char *contentsp, long flags, cm_ReleaseSCache(scp); } } + + free(fnamep); /* and return error code */ return code; @@ -3154,19 +3092,19 @@ long cm_SymLink(cm_scache_t *dscp, char *namep, char *contentsp, long flags, \param[in] dscp cm_scache_t for the directory containing the directory to be removed. - \param[in] namep Non-normalized name of the directory to be - removed. This will be the name that is passed in to - RXAFS_RemoveDir(). + \param[in] fnamep This will be the original name of the directory + as known to the file server. It will be passed in to RXAFS_RemoveDir(). + This parameter is optional. If it is not provided the value + will be looked up. - \param[in] normalizedNamep Normalized name used to update the local + \param[in] cnamep Normalized name used to update the local directory caches. \param[in] userp cm_user_t for the request. \param[in] reqp Request tracker. */ -long cm_RemoveDir(cm_scache_t *dscp, char *namep, char *normalizedNamep, - cm_user_t *userp, cm_req_t *reqp) +long cm_RemoveDir(cm_scache_t *dscp, fschar_t *fnamep, clientchar_t *cnamep, cm_user_t *userp, cm_req_t *reqp) { cm_conn_t *connp; long code; @@ -3177,8 +3115,26 @@ long cm_RemoveDir(cm_scache_t *dscp, char *namep, char *normalizedNamep, struct rx_connection * callp; cm_dirOp_t dirop; cm_scache_t *scp = NULL; + int free_fnamep = FALSE; - code = cm_Lookup(dscp, namep, CM_FLAG_NOMOUNTCHASE, userp, reqp, &scp); + if (fnamep == NULL) { + code = -1; +#ifdef USE_BPLUS + code = cm_BeginDirOp(dscp, userp, reqp, CM_DIRLOCK_READ, &dirop); + if (code == 0) { + code = cm_BPlusDirLookupOriginalName(&dirop, cnamep, &fnamep); + if (code == 0) + free_fnamep = TRUE; + cm_EndDirOp(&dirop); + } +#endif + if (code) + goto done; + } + + code = cm_Lookup(dscp, cnamep, CM_FLAG_NOMOUNTCHASE, userp, reqp, &scp); + if (code) + goto done; /* before starting the RPC, mark that we're changing the directory data, * so that someone who does a chmod on the dir will wait until our @@ -3190,7 +3146,7 @@ long cm_RemoveDir(cm_scache_t *dscp, char *namep, char *normalizedNamep, lock_ReleaseWrite(&dscp->rw); if (code) { cm_EndDirOp(&dirop); - return code; + goto done; } didEnd = 0; @@ -3206,12 +3162,12 @@ long cm_RemoveDir(cm_scache_t *dscp, char *namep, char *normalizedNamep, dirAFSFid.Unique = dscp->fid.unique; callp = cm_GetRxConn(connp); - code = RXAFS_RemoveDir(callp, &dirAFSFid, namep, - &updatedDirStatus, &volSync); + code = RXAFS_RemoveDir(callp, &dirAFSFid, fnamep, + &updatedDirStatus, &volSync); rx_PutConnection(callp); } while (cm_Analyze(connp, userp, reqp, - &dscp->fid, &volSync, NULL, NULL, code)); + &dscp->fid, &volSync, NULL, NULL, code)); code = cm_MapRPCErrorRmdir(code, reqp); if (code) @@ -3226,16 +3182,16 @@ long cm_RemoveDir(cm_scache_t *dscp, char *namep, char *normalizedNamep, lock_ObtainWrite(&dscp->rw); cm_SyncOpDone(dscp, NULL, CM_SCACHESYNC_STOREDATA); if (code == 0) { - cm_dnlcRemove(dscp, normalizedNamep); + cm_dnlcRemove(dscp, cnamep); cm_MergeStatus(NULL, dscp, &updatedDirStatus, &volSync, userp, CM_MERGEFLAG_DIROP); } lock_ReleaseWrite(&dscp->rw); if (code == 0) { - if (cm_CheckDirOpForSingleChange(&dirop) && normalizedNamep != NULL) { - cm_DirDeleteEntry(&dirop, namep); + if (cm_CheckDirOpForSingleChange(&dirop) && cnamep != NULL) { + cm_DirDeleteEntry(&dirop, fnamep); #ifdef USE_BPLUS - cm_BPlusDirDeleteEntry(&dirop, normalizedNamep); + cm_BPlusDirDeleteEntry(&dirop, cnamep); #endif } } @@ -3250,6 +3206,10 @@ long cm_RemoveDir(cm_scache_t *dscp, char *namep, char *normalizedNamep, } } + done: + if (free_fnamep) + free(fnamep); + /* and return error code */ return code; } @@ -3279,8 +3239,9 @@ long cm_Open(cm_scache_t *scp, int type, cm_user_t *userp) \param[in] oldDscp cm_scache_t for the directory containing the old name. - \param[in] oldNamep Non-normalized old name. This is the name that - will be passed into the RXAFS_Rename(). + \param[in] oldNamep The original old name known to the file server. + This is the name that will be passed into the RXAFS_Rename(). + If it is not provided, it will be looked up. \param[in] normalizedOldNamep Normalized old name. This is used for updating local directory caches. @@ -3295,8 +3256,8 @@ long cm_Open(cm_scache_t *scp, int type, cm_user_t *userp) \param[in,out] reqp Request tracker. */ -long cm_Rename(cm_scache_t *oldDscp, char *oldNamep, char *normalizedOldNamep, - cm_scache_t *newDscp, char *newNamep, cm_user_t *userp, +long cm_Rename(cm_scache_t *oldDscp, fschar_t *oldNamep, clientchar_t *cOldNamep, + cm_scache_t *newDscp, clientchar_t *cNewNamep, cm_user_t *userp, cm_req_t *reqp) { cm_conn_t *connp; @@ -3313,6 +3274,24 @@ long cm_Rename(cm_scache_t *oldDscp, char *oldNamep, char *normalizedOldNamep, cm_fid_t fileFid; int diropCode = -1; cm_dirOp_t newDirOp; + fschar_t * newNamep = NULL; + int free_oldNamep = FALSE; + + if (oldNamep == NULL) { + code = -1; +#ifdef USE_BPLUS + code = cm_BeginDirOp(oldDscp, userp, reqp, CM_DIRLOCK_READ, &oldDirOp); + if (code == 0) { + code = cm_BPlusDirLookupOriginalName(&oldDirOp, cOldNamep, &oldNamep); + if (code == 0) + free_oldNamep = TRUE; + cm_EndDirOp(&oldDirOp); + } +#endif + if (code) + goto done; + } + /* before starting the RPC, mark that we're changing the directory data, * so that someone who does a chmod on the dir will wait until our call @@ -3321,14 +3300,16 @@ long cm_Rename(cm_scache_t *oldDscp, char *oldNamep, char *normalizedOldNamep, */ if (oldDscp == newDscp) { /* check for identical names */ - if (strcmp(oldNamep, newNamep) == 0) - return CM_ERROR_RENAME_IDENTICAL; + if (cm_ClientStrCmp(cOldNamep, cNewNamep) == 0) { + code = CM_ERROR_RENAME_IDENTICAL; + goto done; + } oneDir = 1; cm_BeginDirOp(oldDscp, userp, reqp, CM_DIRLOCK_NONE, &oldDirOp); lock_ObtainWrite(&oldDscp->rw); - cm_dnlcRemove(oldDscp, normalizedOldNamep); - cm_dnlcRemove(oldDscp, newNamep); + cm_dnlcRemove(oldDscp, cOldNamep); + cm_dnlcRemove(oldDscp, cNewNamep); code = cm_SyncOp(oldDscp, NULL, userp, reqp, 0, CM_SCACHESYNC_STOREDATA); lock_ReleaseWrite(&oldDscp->rw); @@ -3340,31 +3321,35 @@ long cm_Rename(cm_scache_t *oldDscp, char *oldNamep, char *normalizedOldNamep, /* two distinct dir vnodes */ oneDir = 0; if (oldDscp->fid.cell != newDscp->fid.cell || - oldDscp->fid.volume != newDscp->fid.volume) - return CM_ERROR_CROSSDEVLINK; + oldDscp->fid.volume != newDscp->fid.volume) { + code = CM_ERROR_CROSSDEVLINK; + goto done; + } /* shouldn't happen that we have distinct vnodes for two * different files, but could due to deliberate attack, or * stale info. Avoid deadlocks and quit now. */ - if (oldDscp->fid.vnode == newDscp->fid.vnode) - return CM_ERROR_CROSSDEVLINK; + if (oldDscp->fid.vnode == newDscp->fid.vnode) { + code = CM_ERROR_CROSSDEVLINK; + goto done; + } if (oldDscp->fid.vnode < newDscp->fid.vnode) { cm_BeginDirOp(oldDscp, userp, reqp, CM_DIRLOCK_NONE, &oldDirOp); lock_ObtainWrite(&oldDscp->rw); - cm_dnlcRemove(oldDscp, normalizedOldNamep); + cm_dnlcRemove(oldDscp, cOldNamep); code = cm_SyncOp(oldDscp, NULL, userp, reqp, 0, - CM_SCACHESYNC_STOREDATA); + CM_SCACHESYNC_STOREDATA); lock_ReleaseWrite(&oldDscp->rw); if (code != 0) cm_EndDirOp(&oldDirOp); if (code == 0) { cm_BeginDirOp(newDscp, userp, reqp, CM_DIRLOCK_NONE, &newDirOp); lock_ObtainWrite(&newDscp->rw); - cm_dnlcRemove(newDscp, newNamep); + cm_dnlcRemove(newDscp, cNewNamep); code = cm_SyncOp(newDscp, NULL, userp, reqp, 0, - CM_SCACHESYNC_STOREDATA); + CM_SCACHESYNC_STOREDATA); lock_ReleaseWrite(&newDscp->rw); if (code) { cm_EndDirOp(&newDirOp); @@ -3382,7 +3367,7 @@ long cm_Rename(cm_scache_t *oldDscp, char *oldNamep, char *normalizedOldNamep, /* lock the new vnode entry first */ cm_BeginDirOp(newDscp, userp, reqp, CM_DIRLOCK_NONE, &newDirOp); lock_ObtainWrite(&newDscp->rw); - cm_dnlcRemove(newDscp, newNamep); + cm_dnlcRemove(newDscp, cNewNamep); code = cm_SyncOp(newDscp, NULL, userp, reqp, 0, CM_SCACHESYNC_STOREDATA); lock_ReleaseWrite(&newDscp->rw); @@ -3391,7 +3376,7 @@ long cm_Rename(cm_scache_t *oldDscp, char *oldNamep, char *normalizedOldNamep, if (code == 0) { cm_BeginDirOp(oldDscp, userp, reqp, CM_DIRLOCK_NONE, &oldDirOp); lock_ObtainWrite(&oldDscp->rw); - cm_dnlcRemove(oldDscp, normalizedOldNamep); + cm_dnlcRemove(oldDscp, cOldNamep); code = cm_SyncOp(oldDscp, NULL, userp, reqp, 0, CM_SCACHESYNC_STOREDATA); lock_ReleaseWrite(&oldDscp->rw); @@ -3409,11 +3394,13 @@ long cm_Rename(cm_scache_t *oldDscp, char *oldNamep, char *normalizedOldNamep, } } /* two distinct vnodes */ - if (code) { - return code; - } + if (code) + goto done; + didEnd = 0; + newNamep = cm_ClientStringToFsStringAlloc(cNewNamep, -1, NULL); + /* try the RPC now */ osi_Log2(afsd_logp, "CALL Rename old scp 0x%p new scp 0x%p", oldDscp, newDscp); @@ -3431,9 +3418,9 @@ long cm_Rename(cm_scache_t *oldDscp, char *oldNamep, char *normalizedOldNamep, callp = cm_GetRxConn(connp); code = RXAFS_Rename(callp, &oldDirAFSFid, oldNamep, - &newDirAFSFid, newNamep, - &updatedOldDirStatus, &updatedNewDirStatus, - &volSync); + &newDirAFSFid, newNamep, + &updatedOldDirStatus, &updatedNewDirStatus, + &volSync); rx_PutConnection(callp); } while (cm_Analyze(connp, userp, reqp, &oldDscp->fid, @@ -3455,14 +3442,14 @@ long cm_Rename(cm_scache_t *oldDscp, char *oldNamep, char *normalizedOldNamep, if (code == 0) cm_MergeStatus(NULL, oldDscp, &updatedOldDirStatus, &volSync, - userp, CM_MERGEFLAG_DIROP); + userp, CM_MERGEFLAG_DIROP); lock_ReleaseWrite(&oldDscp->rw); if (code == 0) { if (cm_CheckDirOpForSingleChange(&oldDirOp)) { #ifdef USE_BPLUS - diropCode = cm_BPlusDirLookup(&oldDirOp, normalizedOldNamep, &fileFid); + diropCode = cm_BPlusDirLookup(&oldDirOp, cOldNamep, &fileFid); if (diropCode == CM_ERROR_INEXACT_MATCH) diropCode = 0; else if (diropCode == EINVAL) @@ -3473,14 +3460,14 @@ long cm_Rename(cm_scache_t *oldDscp, char *oldNamep, char *normalizedOldNamep, if (oneDir) { diropCode = cm_DirCreateEntry(&oldDirOp, newNamep, &fileFid); #ifdef USE_BPLUS - cm_BPlusDirCreateEntry(&oldDirOp, newNamep, &fileFid); + cm_BPlusDirCreateEntry(&oldDirOp, cNewNamep, &fileFid); #endif } - + if (diropCode == 0) { diropCode = cm_DirDeleteEntry(&oldDirOp, oldNamep); #ifdef USE_BPLUS - cm_BPlusDirDeleteEntry(&oldDirOp, normalizedOldNamep); + cm_BPlusDirDeleteEntry(&oldDirOp, cOldNamep); #endif } } @@ -3508,13 +3495,19 @@ long cm_Rename(cm_scache_t *oldDscp, char *oldNamep, char *normalizedOldNamep, if (diropCode == 0 && cm_CheckDirOpForSingleChange(&newDirOp)) { cm_DirCreateEntry(&newDirOp, newNamep, &fileFid); #ifdef USE_BPLUS - cm_BPlusDirCreateEntry(&newDirOp, newNamep, &fileFid); + cm_BPlusDirCreateEntry(&newDirOp, cNewNamep, &fileFid); #endif } } cm_EndDirOp(&newDirOp); } + done: + if (free_oldNamep) + free(oldNamep); + + free(newNamep); + /* and return error code */ return code; } diff --git a/src/WINNT/afsd/cm_vnodeops.h b/src/WINNT/afsd/cm_vnodeops.h index a72c0b1..280a885 100644 --- a/src/WINNT/afsd/cm_vnodeops.h +++ b/src/WINNT/afsd/cm_vnodeops.h @@ -18,12 +18,12 @@ extern int cm_followBackupPath; /* parms for attribute setting call */ typedef struct cm_attr { - int mask; - time_t clientModTime; - osi_hyper_t length; - int unixModeBits; - long owner; - long group; + int mask; + time_t clientModTime; + osi_hyper_t length; + int unixModeBits; + long owner; + long group; } cm_attr_t; #define CM_ATTRMASK_CLIENTMODTIME 1 /* set if field is valid */ @@ -34,18 +34,19 @@ typedef struct cm_attr { /* type of rock for lookup's searches */ typedef struct cm_lookupSearch { - cm_fid_t fid; - char *searchNamep; - int found; - int LCfound, UCfound, NCfound, ExactFound; - int caseFold; - int hasTilde; + cm_fid_t fid; + fschar_t *searchNamep; + normchar_t *nsearchNamep; + int found; + int LCfound, UCfound, NCfound, ExactFound; + int caseFold; + int hasTilde; } cm_lookupSearch_t; #include "cm_dir.h" typedef int (*cm_DirFuncp_t)(struct cm_scache *, struct cm_dirEntry *, void *, - osi_hyper_t *entryOffsetp); + osi_hyper_t *entryOffsetp); /* Special path syntax for direct references to volumes @@ -60,107 +61,99 @@ typedef int (*cm_DirFuncp_t)(struct cm_scache *, struct cm_dirEntry *, void *, /* arrays */ -extern unsigned char cm_foldUpper[]; +extern fschar_t cm_foldUpper[]; /* functions */ -extern int cm_NoneLower(char *s); +extern int cm_NoneLower(normchar_t *s); -extern int cm_NoneUpper(char *s); - -extern int cm_Is8Dot3(char *namep); +extern int cm_NoneUpper(normchar_t *s); extern int cm_stricmp(const char *, const char *); -extern void cm_Gen8Dot3Name(struct cm_dirEntry *dep, char *shortName, - char **shortNameEndp); - -#define cm_Gen8Dot3Name(dep,shortName,shortNameEndp) \ -cm_Gen8Dot3NameInt((dep)->name, &(dep)->fid, shortName, shortNameEndp) - -extern void cm_Gen8Dot3NameInt(const char * longname, cm_dirFid_t * pfid, - char *shortName, char **shortNameEndp); - extern long cm_ReadMountPoint(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp); -extern long cm_EvaluateVolumeReference(char * namep, long flags, cm_user_t * userp, +extern long cm_EvaluateVolumeReference(clientchar_t * namep, long flags, cm_user_t * userp, cm_req_t *reqp, cm_scache_t ** outpScpp); #ifdef DEBUG_REFCOUNT -extern long cm_NameIDbg(cm_scache_t *rootSCachep, char *pathp, long flags, - cm_user_t *userp, char *tidPathp, cm_req_t *reqp, - cm_scache_t **outScpp, char *, long); +extern long cm_NameIDbg(cm_scache_t *rootSCachep, clientchar_t *pathp, long flags, + cm_user_t *userp, clientchar_t *tidPathp, cm_req_t *reqp, + cm_scache_t **outScpp, char *, long); -extern long cm_LookupDbg(cm_scache_t *dscp, char *namep, long flags, - cm_user_t *userp, cm_req_t *reqp, cm_scache_t **outpScpp, char *, long); +extern long cm_LookupDbg(cm_scache_t *dscp, clientchar_t *namep, long flags, + cm_user_t *userp, cm_req_t *reqp, cm_scache_t **outpScpp, + char *, long); #define cm_Lookup(a,b,c,d,e,f) cm_LookupDbg(a,b,c,d,e,f,__FILE__,__LINE__) #define cm_NameI(a,b,c,d,e,f,g) cm_NameIDbg(a,b,c,d,e,f,g,__FILE__,__LINE__) #else -extern long cm_NameI(cm_scache_t *rootSCachep, char *pathp, long flags, - cm_user_t *userp, char *tidPathp, cm_req_t *reqp, - cm_scache_t **outScpp); -extern long cm_Lookup(cm_scache_t *dscp, char *namep, long flags, - cm_user_t *userp, cm_req_t *reqp, cm_scache_t **outpScpp); +extern long cm_NameI(cm_scache_t *rootSCachep, clientchar_t *pathp, long flags, + cm_user_t *userp, clientchar_t *tidPathp, cm_req_t *reqp, + cm_scache_t **outScpp); +extern long cm_Lookup(cm_scache_t *dscp, clientchar_t *namep, long flags, + cm_user_t *userp, cm_req_t *reqp, cm_scache_t **outpScpp); #endif -extern long cm_LookupInternal(cm_scache_t *dscp, char *namep, long flags, +extern long cm_LookupInternal(cm_scache_t *dscp, clientchar_t *namep, long flags, cm_user_t *userp, cm_req_t *reqp, cm_scache_t **outpScpp); extern afs_int32 cm_TryBulkStat(cm_scache_t *dscp, osi_hyper_t *offsetp, - cm_user_t *userp, cm_req_t *reqp); + cm_user_t *userp, cm_req_t *reqp); extern long cm_SetAttr(cm_scache_t *scp, cm_attr_t *attrp, cm_user_t *userp, - cm_req_t *reqp); + cm_req_t *reqp); -extern long cm_Create(cm_scache_t *scp, char *namep, long flags, - cm_attr_t *attrp, cm_scache_t **scpp, cm_user_t *userp, cm_req_t *reqp); +extern long cm_Create(cm_scache_t *scp, clientchar_t *namep, long flags, + cm_attr_t *attrp, cm_scache_t **scpp, + cm_user_t *userp, cm_req_t *reqp); extern long cm_FSync(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp); extern void cm_StatusFromAttr(struct AFSStoreStatus *statusp, - struct cm_scache *scp, struct cm_attr *attrp); + struct cm_scache *scp, struct cm_attr *attrp); -extern long cm_Unlink(cm_scache_t *dscp, char *namep, char * normalizedName, +extern long cm_Unlink(cm_scache_t *dscp, fschar_t *fnamep, + clientchar_t *cnamep, cm_user_t *userp, cm_req_t *reqp); extern long cm_ApplyDir(cm_scache_t *scp, cm_DirFuncp_t funcp, void *parmp, - osi_hyper_t *startOffsetp, cm_user_t *userp, cm_req_t *reqp, - cm_scache_t **retscp); + osi_hyper_t *startOffsetp, cm_user_t *userp, cm_req_t *reqp, + cm_scache_t **retscp); -extern long cm_MakeDir(cm_scache_t *dscp, char *lastNamep, long flags, - cm_attr_t *attrp, cm_user_t *userp, cm_req_t *reqp); +extern long cm_MakeDir(cm_scache_t *dscp, clientchar_t *lastNamep, long flags, + cm_attr_t *attrp, cm_user_t *userp, cm_req_t *reqp); -extern long cm_RemoveDir(cm_scache_t *dscp, char *lastNamep, char *originalNamep, +extern long cm_RemoveDir(cm_scache_t *dscp, fschar_t *lastNamep, clientchar_t *originalNamep, cm_user_t *userp, cm_req_t *reqp); extern long cm_Rename(cm_scache_t *oldDscp, - char *oldLastNamep, char *normalizedOldNamep, - cm_scache_t *newDscp, char *newLastNamep, + fschar_t *oldLastNamep, clientchar_t *normalizedOldNamep, + cm_scache_t *newDscp, clientchar_t *newLastNamep, cm_user_t *userp, cm_req_t *reqp); extern long cm_HandleLink(cm_scache_t *linkScp, struct cm_user *userp, - cm_req_t *reqp); + cm_req_t *reqp); -extern long cm_Link(cm_scache_t *dscp, char *namep, cm_scache_t *sscp, - long flags, cm_user_t *userp, cm_req_t *reqp); +extern long cm_Link(cm_scache_t *dscp, clientchar_t *namep, cm_scache_t *sscp, + long flags, cm_user_t *userp, cm_req_t *reqp); -extern long cm_SymLink(cm_scache_t *dscp, char *namep, char *contentsp, - long flags, cm_attr_t *attrp, cm_user_t *userp, cm_req_t *reqp); +extern long cm_SymLink(cm_scache_t *dscp, clientchar_t *namep, fschar_t *contentsp, + long flags, cm_attr_t *attrp, cm_user_t *userp, cm_req_t *reqp); -extern long cm_AssembleLink(cm_scache_t *linkScp, char *pathSuffixp, +extern long cm_AssembleLink(cm_scache_t *linkScp, fschar_t *pathSuffixp, cm_scache_t **newRootScpp, cm_space_t **newSpaceBufferp, cm_user_t *userp, cm_req_t *reqp); -extern int cm_ExpandSysName(char *inp, char *outp, long outSize, +extern int cm_ExpandSysName(clientchar_t *inp, clientchar_t *outp, long outSizeCch, unsigned int sysNameIndex); extern long cm_Open(cm_scache_t *scp, int type, cm_user_t *userp); extern long cm_CheckOpen(cm_scache_t *scp, int openMode, int trunc, - cm_user_t *userp, cm_req_t *reqp); + cm_user_t *userp, cm_req_t *reqp); /* * Combinations of file opening access bits for AFS. @@ -180,47 +173,49 @@ typedef struct cm_lock_data { } cm_lock_data_t; extern long cm_CheckNTOpen(cm_scache_t *scp, unsigned int desiredAccess, - unsigned int createDisp, cm_user_t *userp, cm_req_t *reqp, cm_lock_data_t ** ldpp); + unsigned int createDisp, cm_user_t *userp, + cm_req_t *reqp, cm_lock_data_t ** ldpp); extern long cm_CheckNTOpenDone(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp, cm_lock_data_t ** ldpp); extern long cm_CheckNTDelete(cm_scache_t *dscp, cm_scache_t *scp, - cm_user_t *userp, cm_req_t *reqp); + cm_user_t *userp, cm_req_t *reqp); extern long cm_EvaluateSymLink(cm_scache_t *dscp, cm_scache_t *linkScp, - cm_scache_t **outScpp, cm_user_t *userp, cm_req_t *reqp); + cm_scache_t **outScpp, cm_user_t *userp, + cm_req_t *reqp); extern long cm_FollowMountPoint(cm_scache_t *scp, cm_scache_t *dscp, cm_user_t *userp, cm_req_t *reqp, cm_scache_t **outScpp); extern long cm_Lock(cm_scache_t *scp, unsigned char sLockType, - LARGE_INTEGER LOffset, LARGE_INTEGER LLength, cm_key_t key, - int allowWait, cm_user_t *userp, cm_req_t *reqp, - cm_file_lock_t **lockpp); + LARGE_INTEGER LOffset, LARGE_INTEGER LLength, cm_key_t key, + int allowWait, cm_user_t *userp, cm_req_t *reqp, + cm_file_lock_t **lockpp); #define CM_UNLOCK_BY_FID 0x0001 extern long cm_UnlockByKey(cm_scache_t * scp, - cm_key_t key, - int flags, - cm_user_t * userp, - cm_req_t * reqp); + cm_key_t key, + int flags, + cm_user_t * userp, + cm_req_t * reqp); extern long cm_Unlock(cm_scache_t *scp, unsigned char sLockType, - LARGE_INTEGER LOffset, LARGE_INTEGER LLength, cm_key_t key, - cm_user_t *userp, cm_req_t *reqp); + LARGE_INTEGER LOffset, LARGE_INTEGER LLength, cm_key_t key, + cm_user_t *userp, cm_req_t *reqp); extern long cm_LockCheckRead(cm_scache_t *scp, - LARGE_INTEGER LOffset, - LARGE_INTEGER LLength, - cm_key_t key); + LARGE_INTEGER LOffset, + LARGE_INTEGER LLength, + cm_key_t key); extern long cm_LockCheckWrite(cm_scache_t *scp, - LARGE_INTEGER LOffset, - LARGE_INTEGER LLength, - cm_key_t key); + LARGE_INTEGER LOffset, + LARGE_INTEGER LLength, + cm_key_t key); extern void cm_CheckLocks(void); diff --git a/src/WINNT/afsd/cm_volstat.c b/src/WINNT/afsd/cm_volstat.c index e90183a..3f1a2f6 100644 --- a/src/WINNT/afsd/cm_volstat.c +++ b/src/WINNT/afsd/cm_volstat.c @@ -40,6 +40,7 @@ #include #include #include "afsd.h" +#include "smb.h" #include HMODULE hVolStatus = NULL; @@ -171,7 +172,7 @@ long #ifdef _WIN64 cm_VolStatus_Network_Started(const char * netbios32, const char * netbios64) #else /* _WIN64 */ -cm_VolStatus_Network_Started(const char * netbios) +cm_VolStatus_Network_Started(const char * netbios32) #endif /* _WIN64 */ { long code = 0; @@ -182,7 +183,7 @@ cm_VolStatus_Network_Started(const char * netbios) #ifdef _WIN64 code = dll_funcs.dll_VolStatus_Network_Started(netbios32, netbios64); #else - code = dll_funcs.dll_VolStatus_Network_Started(netbios, netbios); + code = dll_funcs.dll_VolStatus_Network_Started(netbios32, netbios32); #endif return code; @@ -196,7 +197,7 @@ long #ifdef _WIN64 cm_VolStatus_Network_Stopped(const char * netbios32, const char * netbios64) #else /* _WIN64 */ -cm_VolStatus_Network_Stopped(const char * netbios) +cm_VolStatus_Network_Stopped(const char * netbios32) #endif /* _WIN64 */ { long code = 0; @@ -207,7 +208,7 @@ cm_VolStatus_Network_Stopped(const char * netbios) #ifdef _WIN64 code = dll_funcs.dll_VolStatus_Network_Stopped(netbios32, netbios64); #else - code = dll_funcs.dll_VolStatus_Network_Stopped(netbios, netbios); + code = dll_funcs.dll_VolStatus_Network_Stopped(netbios32, netbios32); #endif return code; @@ -250,15 +251,21 @@ cm_VolStatus_Change_Notification(afs_uint32 cellID, afs_uint32 volID, enum volst long -cm_VolStatus_Notify_DFS_Mapping(cm_scache_t *scp, char *tidPathp, char *pathp) +cm_VolStatus_Notify_DFS_Mapping(cm_scache_t *scp, const clientchar_t *ctidPathp, + const clientchar_t *cpathp) { long code = 0; char src[1024], *p; size_t len; + char * tidPathp = NULL; + char * pathp = NULL; if (hVolStatus == NULL || dll_funcs.version < 2) return 0; + tidPathp = cm_ClientStringToUtf8Alloc(ctidPathp, -1, NULL); + pathp = cm_ClientStringToUtf8Alloc(cpathp, -1, NULL); + snprintf(src,sizeof(src), "\\\\%s%s", volstat_NetbiosName, tidPathp); len = strlen(src); if ((src[len-1] == '\\' || src[len-1] == '/') && @@ -275,6 +282,11 @@ cm_VolStatus_Notify_DFS_Mapping(cm_scache_t *scp, char *tidPathp, char *pathp) code = dll_funcs.dll_VolStatus_Notify_DFS_Mapping(scp->fid.cell, scp->fid.volume, scp->fid.vnode, scp->fid.unique, src, scp->mountPointStringp); + if (tidPathp) + free(tidPathp); + if (pathp) + free(pathp); + return code; } @@ -299,6 +311,8 @@ cm_VolStatus_Path_To_ID(const char * share, const char * path, afs_uint32 * cell cm_req_t req; cm_scache_t *scp; cm_volume_t *volp; + clientchar_t * cpath = NULL; + clientchar_t * cshare = NULL; if (cellID == NULL || volID == NULL) return CM_ERROR_INVAL; @@ -308,7 +322,12 @@ cm_VolStatus_Path_To_ID(const char * share, const char * path, afs_uint32 * cell cm_InitReq(&req); - code = cm_NameI(cm_data.rootSCachep, (char *)path, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, cm_rootUserp, (char *)share, &req, &scp); + cpath = cm_FsStringToClientStringAlloc(path, -1, NULL); + cshare = cm_FsStringToClientStringAlloc(share, -1, NULL); + + code = cm_NameI(cm_data.rootSCachep, cpath, + CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, + cm_rootUserp, cshare, &req, &scp); if (code) goto done; @@ -336,6 +355,11 @@ cm_VolStatus_Path_To_ID(const char * share, const char * path, afs_uint32 * cell cm_ReleaseSCache(scp); done: + if (cpath) + free(cpath); + if (cshare) + free(cshare); + osi_Log1(afsd_logp,"cm_VolStatus_Path_To_ID code 0x%x",code); return code; } @@ -347,6 +371,8 @@ cm_VolStatus_Path_To_DFSlink(const char * share, const char * path, afs_uint32 * cm_req_t req; cm_scache_t *scp; size_t len; + clientchar_t *cpath = NULL; + clientchar_t *cshare = NULL; if (pBufSize == NULL || (pBuffer == NULL && *pBufSize != 0)) return CM_ERROR_INVAL; @@ -356,8 +382,11 @@ cm_VolStatus_Path_To_DFSlink(const char * share, const char * path, afs_uint32 * cm_InitReq(&req); - code = cm_NameI(cm_data.rootSCachep, (char *)path, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, - cm_rootUserp, (char *)share, &req, &scp); + cpath = cm_FsStringToClientStringAlloc(path, -1, NULL); + cshare = cm_FsStringToClientStringAlloc(share, -1, NULL); + + code = cm_NameI(cm_data.rootSCachep, cpath, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, + cm_rootUserp, cshare, &req, &scp); if (code) goto done; @@ -392,6 +421,11 @@ cm_VolStatus_Path_To_DFSlink(const char * share, const char * path, afs_uint32 * cm_ReleaseSCache(scp); done: + if (cpath) + free(cpath); + if (cshare) + free(cshare); + osi_Log1(afsd_logp,"cm_VolStatus_Path_To_DFSlink code 0x%x",code); return code; } diff --git a/src/WINNT/afsd/cm_volstat.h b/src/WINNT/afsd/cm_volstat.h index 84016aa..a9d0118 100644 --- a/src/WINNT/afsd/cm_volstat.h +++ b/src/WINNT/afsd/cm_volstat.h @@ -42,9 +42,11 @@ extern long cm_VolStatus_Service_Started(void); extern long cm_VolStatus_Service_Stopped(void); #ifdef _WIN64 -extern long cm_VolStatus_Network_Started(const char * netbios32, const char * netbios64); +extern long cm_VolStatus_Network_Started(const char * netbios32, + const char * netbios64); -extern long cm_VolStatus_Network_Stopped(const char * netbios32, const char * netbios64); +extern long cm_VolStatus_Network_Stopped(const char * netbios32, + const char * netbios64); #else /* _WIN64 */ extern long cm_VolStatus_Network_Started(const char * netbios); @@ -55,11 +57,19 @@ extern long cm_VolStatus_Network_Addr_Change(void); extern long cm_VolStatus_Change_Notification(afs_uint32 cellID, afs_uint32 volID, enum volstatus status); -extern long __fastcall cm_VolStatus_Path_To_ID(const char * share, const char * path, afs_uint32 * cellID, afs_uint32 * volID, enum volstatus *pstatus); +extern long __fastcall cm_VolStatus_Path_To_ID(const char * share, + const char * path, + afs_uint32 * cellID, afs_uint32 * volID, + enum volstatus *pstatus); -extern long __fastcall cm_VolStatus_Path_To_DFSlink(const char * share, const char * path, afs_uint32 *pBufSize, char *pBuffer); +extern long __fastcall cm_VolStatus_Path_To_DFSlink(const char * share, + const char * path, + afs_uint32 *pBufSize, + char *pBuffer); -extern long cm_VolStatus_Notify_DFS_Mapping(cm_scache_t *scp, char *tidPathp, char *pathp); +extern long cm_VolStatus_Notify_DFS_Mapping(cm_scache_t *scp, + const clientchar_t *tidPathp, + const clientchar_t *pathp); extern long cm_VolStatus_Invalidate_DFS_Mapping(cm_scache_t *scp); diff --git a/src/WINNT/afsd/smb.c b/src/WINNT/afsd/smb.c index 91fff17..f073b81 100644 --- a/src/WINNT/afsd/smb.c +++ b/src/WINNT/afsd/smb.c @@ -35,7 +35,7 @@ #include /* These characters are illegal in Windows filenames */ -static char *illegalChars = "\\/:*?\"<>|"; +static clientchar_t *illegalChars = _C("\\/:*?\"<>|"); static int smbShutdownFlag = 0; static int smb_ListenerState = SMB_LISTENER_UNINITIALIZED; @@ -63,7 +63,7 @@ osi_rwlock_t smb_globalLock; osi_rwlock_t smb_rctLock; osi_mutex_t smb_ListenerLock; osi_mutex_t smb_StartedLock; - + unsigned char smb_LANadapter = LANA_INVALID; unsigned char smb_sharename[NCBNAMSZ+1] = {0}; int smb_LanAdapterChangeDetected = 0; @@ -120,12 +120,12 @@ char *smb_RawBufs; /* for raw write */ typedef struct raw_write_cont { - long code; - osi_hyper_t offset; - long count; - char *buf; - int writeMode; - long alreadyWritten; + long code; + osi_hyper_t offset; + long count; + char *buf; + int writeMode; + long alreadyWritten; } raw_write_cont_t; /* dir search stuff */ @@ -142,9 +142,10 @@ LONG smb_UseUnicode; /* global state about V3 protocols */ int smb_useV3; /* try to negotiate V3 */ -static showErrors = 0; +static int showErrors = 0; /* MessageBox or something like it */ -int (_stdcall *smb_MBfunc)(HWND, LPCTSTR, LPCTSTR, UINT) = NULL; +int (_stdcall *smb_MBfunc)(HWND, LPCTSTR, LPCTSTR, UINT) += NULL; /* GMT time info: * Time in Unix format of midnight, 1/1/1970 local time. @@ -178,13 +179,13 @@ int smb_NetbiosInit(int); #ifdef LOG_PACKET void smb_LogPacket(smb_packet_t *packet); #endif /* LOG_PACKET */ - -char smb_ServerDomainName[MAX_COMPUTERNAME_LENGTH + 1] = ""; /* domain name */ + +clientchar_t smb_ServerDomainName[MAX_COMPUTERNAME_LENGTH + 1] = _C(""); /* domain name */ int smb_ServerDomainNameLength = 0; -char smb_ServerOS[] = "Windows 5.0"; /* Faux OS String */ -int smb_ServerOSLength = sizeof(smb_ServerOS); -char smb_ServerLanManager[] = "Windows 2000 LAN Manager"; /* Faux LAN Manager string */ -int smb_ServerLanManagerLength = sizeof(smb_ServerLanManager); +clientchar_t smb_ServerOS[] = _C("Windows 5.0"); /* Faux OS String */ +int smb_ServerOSLength = lengthof(smb_ServerOS); +clientchar_t smb_ServerLanManager[] = _C("Windows 2000 LAN Manager"); /* Faux LAN Manager string */ +int smb_ServerLanManagerLength = lengthof(smb_ServerLanManager); /* Faux server GUID. This is never checked. */ GUID smb_ServerGUID = { 0x40015cb8, 0x058a, 0x44fc, { 0xae, 0x7e, 0xbb, 0x29, 0x52, 0xee, 0x7e, 0xff }}; @@ -493,8 +494,9 @@ unsigned int smb_Attributes(cm_scache_t *scp) /* Check if the named file/dir is a dotfile/dotdir */ /* String pointed to by lastComp can have leading slashes, but otherwise should have no other patch components */ -unsigned int smb_IsDotFile(char *lastComp) { - char *s; +unsigned int smb_IsDotFile(clientchar_t *lastComp) { + clientchar_t *s; + if(lastComp) { /* skip over slashes */ for(s=lastComp;*s && (*s == '\\' || *s == '/'); s++); @@ -503,12 +505,12 @@ unsigned int smb_IsDotFile(char *lastComp) { return 0; /* nulls, curdir and parent dir doesn't count */ - if (!*s) + if (!*s) return 0; - if (*s == '.') { + if (*s == _C('.')) { if (!*(s + 1)) return 0; - if(*(s+1) == '.' && !*(s + 2)) + if(*(s+1) == _C('.') && !*(s + 2)) return 0; return 1; } @@ -895,16 +897,16 @@ smb_vc_t *smb_FindVC(unsigned short lsn, int flags, int lana) return vcp; } -int smb_IsStarMask(char *maskp) +int smb_IsStarMask(clientchar_t *maskp) { int i; - char tc; + clientchar_t tc; for(i=0; i<11; i++) { tc = *maskp++; - if (tc == '?' || tc == '*' || tc == '>') + if (tc == _C('?') || tc == _C('*') || tc == _C('>')) return 1; - } + } return 0; } @@ -1087,7 +1089,7 @@ smb_tid_t *smb_FindTID(smb_vc_t *vcp, unsigned short tid, int flags) if (tid == tidp->tid) { tidp->refCount++; break; - } + } } if (!tidp && (flags & SMB_FLAG_CREATE)) { tidp = malloc(sizeof(*tidp)); @@ -1102,7 +1104,7 @@ smb_tid_t *smb_FindTID(smb_vc_t *vcp, unsigned short tid, int flags) } lock_ReleaseWrite(&smb_rctLock); return tidp; -} +} void smb_HoldTIDNoLock(smb_tid_t *tidp) { @@ -1147,9 +1149,9 @@ smb_user_t *smb_FindUID(smb_vc_t *vcp, unsigned short uid, int flags) for(uidp = vcp->usersp; uidp; uidp = uidp->nextp) { if (uid == uidp->userID) { uidp->refCount++; - osi_Log3(smb_logp, "smb_FindUID vcp[0x%p] found-uid[%d] name[%s]", + osi_Log3(smb_logp, "smb_FindUID vcp[0x%p] found-uid[%d] name[%S]", vcp, uidp->userID, - osi_LogSaveString(smb_logp, (uidp->unp) ? uidp->unp->name : "")); + ((uidp->unp)? osi_LogSaveClientString(smb_logp, uidp->unp->name):_C(""))); break; } } @@ -1163,22 +1165,23 @@ smb_user_t *smb_FindUID(smb_vc_t *vcp, unsigned short uid, int flags) vcp->usersp = uidp; lock_InitializeMutex(&uidp->mx, "user_t mutex"); uidp->userID = uid; - osi_Log3(smb_logp, "smb_FindUID vcp[0x%p] new-uid[%d] name[%s]", - vcp, uidp->userID, - osi_LogSaveString(smb_logp,uidp->unp ? uidp->unp->name : "")); + osi_Log3(smb_logp, "smb_FindUID vcp[0x%p] new-uid[%d] name[%S]", + vcp, uidp->userID, + ((uidp->unp)?osi_LogSaveClientString(smb_logp,uidp->unp->name):_C(""))); } lock_ReleaseWrite(&smb_rctLock); return uidp; } -smb_username_t *smb_FindUserByName(char *usern, char *machine, afs_uint32 flags) +smb_username_t *smb_FindUserByName(clientchar_t *usern, clientchar_t *machine, + afs_uint32 flags) { smb_username_t *unp= NULL; lock_ObtainWrite(&smb_rctLock); for(unp = usernamesp; unp; unp = unp->nextp) { - if (cm_stricmp_utf8(unp->name, usern) == 0 && - cm_stricmp_utf8(unp->machine, machine) == 0) { + if (cm_ClientStrCmpI(unp->name, usern) == 0 && + cm_ClientStrCmpI(unp->machine, machine) == 0) { unp->refCount++; break; } @@ -1188,8 +1191,8 @@ smb_username_t *smb_FindUserByName(char *usern, char *machine, afs_uint32 flags) memset(unp, 0, sizeof(*unp)); unp->refCount = 1; unp->nextp = usernamesp; - unp->name = strdup(usern); - unp->machine = strdup(machine); + unp->name = cm_ClientStrDup(usern); + unp->machine = cm_ClientStrDup(machine); usernamesp = unp; lock_InitializeMutex(&unp->mx, "username_t mutex"); if (flags & SMB_FLAG_AFSLOGON) @@ -1200,7 +1203,7 @@ smb_username_t *smb_FindUserByName(char *usern, char *machine, afs_uint32 flags) return unp; } -smb_user_t *smb_FindUserByNameThisSession(smb_vc_t *vcp, char *usern) +smb_user_t *smb_FindUserByNameThisSession(smb_vc_t *vcp, clientchar_t *usern) { smb_user_t *uidp= NULL; @@ -1208,10 +1211,10 @@ smb_user_t *smb_FindUserByNameThisSession(smb_vc_t *vcp, char *usern) for(uidp = vcp->usersp; uidp; uidp = uidp->nextp) { if (!uidp->unp) continue; - if (cm_stricmp_utf8(uidp->unp->name, usern) == 0) { + if (cm_stricmp_utf16(uidp->unp->name, usern) == 0) { uidp->refCount++; - osi_Log3(smb_logp,"smb_FindUserByNameThisSession vcp[0x%p] uid[%d] match-name[%s]", - vcp,uidp->userID,osi_LogSaveString(smb_logp,usern)); + osi_Log3(smb_logp,"smb_FindUserByNameThisSession vcp[0x%p] uid[%d] match-name[%S]", + vcp,uidp->userID,osi_LogSaveClientString(smb_logp,usern)); break; } else continue; @@ -1244,7 +1247,7 @@ void smb_ReleaseUsername(smb_username_t *unp) free(unp->name); free(unp->machine); free(unp); - } + } lock_ReleaseWrite(&smb_rctLock); if (userp) cm_ReleaseUser(userp); @@ -1329,7 +1332,7 @@ cm_user_t *smb_GetUserFromVCP(smb_vc_t *vcp, smb_packet_t *inp) * Return a pointer to a pathname extracted from a TID structure. The * TID structure is not held; assume it won't go away. */ -long smb_LookupTIDPath(smb_vc_t *vcp, unsigned short tid, char ** treepath) +long smb_LookupTIDPath(smb_vc_t *vcp, unsigned short tid, clientchar_t ** treepath) { smb_tid_t *tidp; long code = 0; @@ -1539,12 +1542,12 @@ void smb_ReleaseFID(smb_fid_t *fidp) * Case-insensitive search for one string in another; * used to find variable names in submount pathnames. */ -static char *smb_stristr(char *str1, char *str2) +static clientchar_t *smb_stristr(clientchar_t *str1, clientchar_t *str2) { - char *cursor; + clientchar_t *cursor; for (cursor = str1; *cursor; cursor++) - if (cm_stricmp_utf8(cursor, str2) == 0) + if (cm_ClientStrCmpI(cursor, str2) == 0) return cursor; return NULL; @@ -1555,25 +1558,24 @@ static char *smb_stristr(char *str1, char *str2) * name has been identified by smb_stristr() and is in substr. Variable name * length (plus one) is in substr_size. Variable value is in newstr. */ -static void smb_subst(char *str1, char *substr, unsigned int substr_size, - char *newstr) +static void smb_subst(clientchar_t *str1, int cchstr1, clientchar_t *substr, + unsigned int substr_size, clientchar_t *newstr) { - char temp[1024]; + clientchar_t temp[1024]; - strcpy(temp, substr + substr_size - 1); - strcpy(substr, newstr); - strcat(str1, temp); -} - -char VNUserName[] = "%USERNAME%"; -char VNLCUserName[] = "%LCUSERNAME%"; -char VNComputerName[] = "%COMPUTERNAME%"; -char VNLCComputerName[] = "%LCCOMPUTERNAME%"; + cm_ClientStrCpy(temp, lengthof(temp), substr + substr_size - 1); + cm_ClientStrCpy(substr, cchstr1 - (substr - str1), newstr); + cm_ClientStrCat(str1, cchstr1, temp); +} +clientchar_t VNUserName[] = _C("%USERNAME%"); +clientchar_t VNLCUserName[] = _C("%LCUSERNAME%"); +clientchar_t VNComputerName[] = _C("%COMPUTERNAME%"); +clientchar_t VNLCComputerName[] = _C("%LCCOMPUTERNAME%"); typedef struct smb_findShare_rock { - char * shareName; - char * match; + clientchar_t * shareName; + clientchar_t * match; int matchType; } smb_findShare_rock_t; @@ -1585,17 +1587,17 @@ long smb_FindShareProc(cm_scache_t *scp, cm_dirEntry_t *dep, void *rockp, { int matchType = 0; smb_findShare_rock_t * vrock = (smb_findShare_rock_t *) rockp; - char normName[MAX_PATH]; + normchar_t normName[MAX_PATH]; - cm_NormalizeUtf8String(dep->name, -1, normName, sizeof(normName)/sizeof(char)); + cm_FsStringToNormString(dep->name, -1, normName, sizeof(normName)/sizeof(normName[0])); - if (!strnicmp(normName, vrock->shareName, 12)) { - if(!cm_stricmp_utf8(normName, vrock->shareName)) + if (!cm_ClientStrCmpNI(normName, vrock->shareName, 12)) { + if(!cm_ClientStrCmpI(normName, vrock->shareName)) matchType = SMB_FINDSHARE_EXACT_MATCH; else matchType = SMB_FINDSHARE_PARTIAL_MATCH; if(vrock->match) free(vrock->match); - vrock->match = strdup(normName); + vrock->match = cm_FsStringToClientStringAlloc(dep->name, -1, NULL); vrock->matchType = matchType; if(matchType == SMB_FINDSHARE_EXACT_MATCH) @@ -1606,15 +1608,17 @@ long smb_FindShareProc(cm_scache_t *scp, cm_dirEntry_t *dep, void *rockp, /* find a shareName in the table of submounts */ -int smb_FindShare(smb_vc_t *vcp, smb_user_t *uidp, char *shareName, - char **pathNamep) -{ - DWORD len; - char pathName[1024]; - char *var; - char temp[1024]; +int smb_FindShare(smb_vc_t *vcp, smb_user_t *uidp, + clientchar_t *shareName, + clientchar_t **pathNamep) +{ + DWORD cblen; + DWORD cchlen; + clientchar_t pathName[1024]; + clientchar_t *var; DWORD sizeTemp; - char *p, *q; + clientchar_t *p, *q; + fschar_t *cellname = NULL; HKEY parmKey; DWORD code; DWORD allSubmount = 1; @@ -1625,18 +1629,18 @@ int smb_FindShare(smb_vc_t *vcp, smb_user_t *uidp, char *shareName, * world to do so. */ code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY, - 0, KEY_QUERY_VALUE, &parmKey); + 0, KEY_QUERY_VALUE, &parmKey); if (code == ERROR_SUCCESS) { - len = sizeof(allSubmount); + cblen = sizeof(allSubmount); code = RegQueryValueEx(parmKey, "AllSubmount", NULL, NULL, - (BYTE *) &allSubmount, &len); + (BYTE *) &allSubmount, &cblen); if (code != ERROR_SUCCESS) { allSubmount = 1; } RegCloseKey (parmKey); } - if (allSubmount && cm_stricmp_utf8N(shareName, "all") == 0) { + if (allSubmount && cm_ClientStrCmpI(shareName, _C("all")) == 0) { *pathNamep = NULL; return 1; } @@ -1644,17 +1648,17 @@ int smb_FindShare(smb_vc_t *vcp, smb_user_t *uidp, char *shareName, /* In case, the all share is disabled we need to still be able * to handle ioctl requests */ - if (cm_stricmp_utf8N(shareName, "ioctl$") == 0) { - *pathNamep = strdup("/.__ioctl__"); + if (cm_ClientStrCmpI(shareName, _C("ioctl$")) == 0) { + *pathNamep = cm_ClientStrDup(_C("/.__ioctl__")); return 1; } - if (cm_stricmp_utf8N(shareName, "IPC$") == 0 || - cm_stricmp_utf8N(shareName, "srvsvc") == 0 || - cm_stricmp_utf8N(shareName, "wkssvc") == 0 || - cm_stricmp_utf8N(shareName, SMB_IOCTL_FILENAME_NOSLASH) == 0 || - cm_stricmp_utf8N(shareName, "DESKTOP.INI") == 0 - ) { + if (cm_ClientStrCmpIA(shareName, _C("IPC$")) == 0 || + cm_ClientStrCmpIA(shareName, _C("srvsvc")) == 0 || + cm_ClientStrCmpIA(shareName, _C("wkssvc")) == 0 || + cm_ClientStrCmpIA(shareName, _C(SMB_IOCTL_FILENAME_NOSLASH)) == 0 || + cm_ClientStrCmpIA(shareName, _C("DESKTOP.INI")) == 0 + ) { *pathNamep = NULL; return 0; } @@ -1663,25 +1667,24 @@ int smb_FindShare(smb_vc_t *vcp, smb_user_t *uidp, char *shareName, * * They look like {%,#} */ - if (strchr(shareName, '%') != NULL || - strchr(shareName, '#') != NULL) { - char pathstr[CELL_MAXNAMELEN + VL_MAXNAMELEN + 1 + CM_PREFIX_VOL_CCH]; - /* make room for '/@vol:' + mountchar + NULL terminator*/ + if (cm_ClientStrChr(shareName, '%') != NULL || + cm_ClientStrChr(shareName, '#') != NULL) { + clientchar_t pathstr[CELL_MAXNAMELEN + VL_MAXNAMELEN + 1 + CM_PREFIX_VOL_CCH]; + /* make room for '/@vol:' + mountchar + NULL terminator*/ - osi_Log1(smb_logp, "smb_FindShare found volume reference [%s]", - osi_LogSaveString(smb_logp, shareName)); + osi_Log1(smb_logp, "smb_FindShare found volume reference [%S]", + osi_LogSaveClientString(smb_logp, shareName)); - snprintf(pathstr, sizeof(pathstr)/sizeof(char), - "/" CM_PREFIX_VOL "%s", shareName); - pathstr[sizeof(pathstr)/sizeof(char) - 1] = '\0'; - len = (DWORD)(strlen(pathstr) + 1); + cm_ClientStrPrintfN(pathstr, lengthof(pathstr), + _C("/") _C(CM_PREFIX_VOL) _C("%s"), shareName); + cchlen = (DWORD)(cm_ClientStrLen(pathstr) + 1); - *pathNamep = malloc(len); + *pathNamep = malloc(cchlen * sizeof(clientchar_t)); if (*pathNamep) { - strcpy(*pathNamep, pathstr); - strlwr(*pathNamep); - osi_Log1(smb_logp, " returning pathname [%s]", - osi_LogSaveString(smb_logp, *pathNamep)); + cm_ClientStrCpy(*pathNamep, cchlen, pathstr); + cm_ClientStrLwr(*pathNamep); + osi_Log1(smb_logp, " returning pathname [%S]", + osi_LogSaveClientString(smb_logp, *pathNamep)); return 1; } else { @@ -1690,64 +1693,75 @@ int smb_FindShare(smb_vc_t *vcp, smb_user_t *uidp, char *shareName, } code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_OPENAFS_SUBKEY "\\Submounts", - 0, KEY_QUERY_VALUE, &parmKey); + 0, KEY_QUERY_VALUE, &parmKey); if (code == ERROR_SUCCESS) { - len = sizeof(pathName); - code = RegQueryValueEx(parmKey, shareName, NULL, NULL, - (BYTE *) pathName, &len); + cblen = sizeof(pathName); + code = RegQueryValueExW(parmKey, shareName, NULL, NULL, + (BYTE *) pathName, &cblen); if (code != ERROR_SUCCESS) - len = 0; + cblen = 0; RegCloseKey (parmKey); } else { - len = 0; - } - if (len != 0 && len != sizeof(pathName) - 1) { + cblen = 0; + } + cchlen = cblen / sizeof(clientchar_t); + if (cchlen != 0 && cchlen != lengthof(pathName) - 1) { /* We can accept either unix or PC style AFS pathnames. Convert * Unix-style to PC style here for internal use. */ p = pathName; - if (strncmp(p, cm_mountRoot, strlen(cm_mountRoot)) == 0) - p += strlen(cm_mountRoot); /* skip mount path */ + cchlen = lengthof(pathName); + + /* within this code block, we maintain, cchlen = writeable + buffer length of p */ + + if (cm_ClientStrCmpN(p, cm_mountRootC, cm_mountRootCLen) == 0) { + p += cm_mountRootCLen; /* skip mount path */ + cchlen -= (p - pathName); + } + q = p; while (*q) { - if (*q == '/') *q = '\\'; /* change to \ */ + if (*q == _C('/')) *q = _C('\\'); /* change to \ */ q++; } while (1) { + clientchar_t temp[1024]; + if (var = smb_stristr(p, VNUserName)) { if (uidp && uidp->unp) - smb_subst(p, var, sizeof(VNUserName),uidp->unp->name); + smb_subst(p, cchlen, var, lengthof(VNUserName),uidp->unp->name); else - smb_subst(p, var, sizeof(VNUserName)," "); + smb_subst(p, cchlen, var, lengthof(VNUserName), _C(" ")); } else if (var = smb_stristr(p, VNLCUserName)) { if (uidp && uidp->unp) - strcpy(temp, uidp->unp->name); + cm_ClientStrCpy(temp, lengthof(temp), uidp->unp->name); else - strcpy(temp, " "); - _strlwr(temp); - smb_subst(p, var, sizeof(VNLCUserName), temp); + cm_ClientStrCpy(temp, lengthof(temp), _C(" ")); + cm_ClientStrLwr(temp); + smb_subst(p, cchlen, var, lengthof(VNLCUserName), temp); } else if (var = smb_stristr(p, VNComputerName)) { - sizeTemp = sizeof(temp); - GetComputerName((LPTSTR)temp, &sizeTemp); - smb_subst(p, var, sizeof(VNComputerName), temp); + sizeTemp = lengthof(temp); + GetComputerNameW(temp, &sizeTemp); + smb_subst(p, cchlen, var, lengthof(VNComputerName), temp); } else if (var = smb_stristr(p, VNLCComputerName)) { - sizeTemp = sizeof(temp); + sizeTemp = lengthof(temp); GetComputerName((LPTSTR)temp, &sizeTemp); - _strlwr(temp); - smb_subst(p, var, sizeof(VNLCComputerName), temp); + cm_ClientStrLwr(temp); + smb_subst(p, cchlen, var, lengthof(VNLCComputerName), temp); } else break; } - *pathNamep = strdup(p); + *pathNamep = cm_ClientStrDup(p); return 1; } else @@ -1756,7 +1770,8 @@ int smb_FindShare(smb_vc_t *vcp, smb_user_t *uidp, char *shareName, cm_req_t req; smb_findShare_rock_t vrock; osi_hyper_t thyper; - char * p = shareName; + fschar_t ftemp[1024]; + clientchar_t * p = shareName; int rw = 0; /* attempt to locate a partial match in root.afs. This is because @@ -1766,18 +1781,21 @@ int smb_FindShare(smb_vc_t *vcp, smb_user_t *uidp, char *shareName, thyper.HighPart = 0; thyper.LowPart = 0; - vrock.shareName = shareName; + vrock.shareName = cm_ClientStringToNormStringAlloc(shareName, -1, NULL); vrock.match = NULL; vrock.matchType = 0; cm_HoldSCache(cm_data.rootSCachep); code = cm_ApplyDir(cm_data.rootSCachep, smb_FindShareProc, &vrock, &thyper, - (uidp? (uidp->unp ? uidp->unp->userp : NULL) : NULL), &req, NULL); + (uidp? (uidp->unp ? uidp->unp->userp : NULL) : NULL), &req, NULL); cm_ReleaseSCache(cm_data.rootSCachep); + free(vrock.shareName); + vrock.shareName = NULL; + if (vrock.matchType) { - sprintf(pathName,"/%s/",vrock.match); - *pathNamep = strdup(strlwr(pathName)); + cm_ClientStrPrintfN(pathName, lengthof(pathName), _C("/%s/"), vrock.match); + *pathNamep = cm_ClientStrDup(cm_ClientStrLwr(pathName)); free(vrock.match); return 1; } @@ -1789,17 +1807,25 @@ int smb_FindShare(smb_vc_t *vcp, smb_user_t *uidp, char *shareName, rw = 1; } /* Get the full name for this cell */ - code = cm_SearchCellFile(p, temp, 0, 0); + cellname = cm_ClientStringToFsStringAlloc(p, cm_ClientStrLen(p), NULL); + code = cm_SearchCellFile(cellname, ftemp, 0, 0); #ifdef AFS_AFSDB_ENV if (code && cm_dnsEnabled) { int ttl; - code = cm_SearchCellByDNS(p, temp, &ttl, 0, 0); + code = cm_SearchCellByDNS(cellname, ftemp, &ttl, 0, 0); } #endif + if (cellname) + free(cellname); + /* construct the path */ - if (code == 0) { - sprintf(pathName,rw ? "/.%s/" : "/%s/",temp); - *pathNamep = strdup(strlwr(pathName)); + if (code == 0) { + clientchar_t temp[1024]; + + cm_FsStringToClientString(ftemp, cm_FsStrLen(ftemp), temp, 1024); + cm_ClientStrPrintfN(pathName, lengthof(pathName), + rw ? _C("/.%S/") : _C("/%S/"), temp); + *pathNamep = cm_ClientStrDup(cm_ClientStrLwr(pathName)); return 1; } } @@ -1814,10 +1840,10 @@ int smb_FindShare(smb_vc_t *vcp, smb_user_t *uidp, char *shareName, #define CSC_POLICY_PROGRAMS 2 #define CSC_POLICY_DISABLE 3 -int smb_FindShareCSCPolicy(char *shareName) +int smb_FindShareCSCPolicy(clientchar_t *shareName) { DWORD len; - char policy[1024]; + clientchar_t policy[1024]; DWORD dwType; HKEY hkCSCPolicy; int retval = CSC_POLICY_MANUAL; @@ -1833,19 +1859,19 @@ int smb_FindShareCSCPolicy(char *shareName) NULL ); len = sizeof(policy); - if ( RegQueryValueEx( hkCSCPolicy, shareName, 0, &dwType, policy, &len ) || + if ( RegQueryValueExW( hkCSCPolicy, shareName, 0, &dwType, (LPBYTE) policy, &len ) || len == 0) { - retval = cm_stricmp_utf8N("all",shareName) ? CSC_POLICY_MANUAL : CSC_POLICY_DISABLE; + retval = cm_ClientStrCmpIA(_C("all"),shareName) ? CSC_POLICY_MANUAL : CSC_POLICY_DISABLE; } - else if (cm_stricmp_utf8N(policy, "documents") == 0) + else if (cm_ClientStrCmpIA(policy, _C("documents")) == 0) { retval = CSC_POLICY_DOCUMENTS; } - else if (cm_stricmp_utf8N(policy, "programs") == 0) + else if (cm_ClientStrCmpIA(policy, _C("programs")) == 0) { retval = CSC_POLICY_PROGRAMS; } - else if (cm_stricmp_utf8N(policy, "disable") == 0) + else if (cm_ClientStrCmpIA(policy, _C("disable")) == 0) { retval = CSC_POLICY_DISABLE; } @@ -2312,7 +2338,7 @@ unsigned int smb_GetSMBOffsetParm(smb_packet_t *smbp, int parm, int offset) void smb_SetSMBParm(smb_packet_t *smbp, int slot, unsigned int parmValue) { - char *parmDatap; + unsigned char *parmDatap; /* make sure we have enough slots */ if (*smbp->wctp <= slot) @@ -2325,7 +2351,7 @@ void smb_SetSMBParm(smb_packet_t *smbp, int slot, unsigned int parmValue) void smb_SetSMBParmLong(smb_packet_t *smbp, int slot, unsigned int parmValue) { - char *parmDatap; + unsigned char *parmDatap; /* make sure we have enough slots */ if (*smbp->wctp <= slot) @@ -2340,7 +2366,7 @@ void smb_SetSMBParmLong(smb_packet_t *smbp, int slot, unsigned int parmValue) void smb_SetSMBParmDouble(smb_packet_t *smbp, int slot, char *parmValuep) { - char *parmDatap; + unsigned char *parmDatap; int i; /* make sure we have enough slots */ @@ -2354,7 +2380,7 @@ void smb_SetSMBParmDouble(smb_packet_t *smbp, int slot, char *parmValuep) void smb_SetSMBParmByte(smb_packet_t *smbp, int slot, unsigned int parmValue) { - char *parmDatap; + unsigned char *parmDatap; /* make sure we have enough slots */ if (*smbp->wctp <= slot) { @@ -2371,11 +2397,12 @@ void smb_SetSMBParmByte(smb_packet_t *smbp, int slot, unsigned int parmValue) -void smb_StripLastComponent(char *outPathp, char **lastComponentp, char *inPathp) +void smb_StripLastComponent(clientchar_t *outPathp, clientchar_t **lastComponentp, + clientchar_t *inPathp) { - char *lastSlashp; + clientchar_t *lastSlashp; - lastSlashp = strrchr(inPathp, '\\'); + lastSlashp = cm_ClientStrRChr(inPathp, '\\'); if (lastComponentp) *lastComponentp = lastSlashp; if (lastSlashp) { @@ -2391,8 +2418,8 @@ void smb_StripLastComponent(char *outPathp, char **lastComponentp, char *inPathp } } -unsigned char *smb_ParseASCIIBlock(smb_packet_t * pktp, unsigned char *inp, - char **chainpp, int flags) +clientchar_t *smb_ParseASCIIBlock(smb_packet_t * pktp, unsigned char *inp, + char **chainpp, int flags) { size_t cb; @@ -2414,8 +2441,8 @@ unsigned char *smb_ParseASCIIBlock(smb_packet_t * pktp, unsigned char *inp, return smb_ParseStringBuf(pktp->data, &pktp->stringsp, inp, &cb, chainpp, flags); } -unsigned char *smb_ParseString(smb_packet_t * pktp, unsigned char * inp, - char ** chainpp, int flags) +clientchar_t *smb_ParseString(smb_packet_t * pktp, unsigned char * inp, + char ** chainpp, int flags) { size_t cb; @@ -2434,8 +2461,8 @@ unsigned char *smb_ParseString(smb_packet_t * pktp, unsigned char * inp, return smb_ParseStringBuf(pktp->data, &pktp->stringsp, inp, &cb, chainpp, flags); } -unsigned char *smb_ParseStringCb(smb_packet_t * pktp, unsigned char * inp, - size_t cb, char ** chainpp, int flags) +clientchar_t *smb_ParseStringCb(smb_packet_t * pktp, unsigned char * inp, + size_t cb, char ** chainpp, int flags) { #ifdef SMB_UNICODE if (!WANTS_UNICODE(pktp)) @@ -2445,8 +2472,8 @@ unsigned char *smb_ParseStringCb(smb_packet_t * pktp, unsigned char * inp, return smb_ParseStringBuf(pktp->data, &pktp->stringsp, inp, &cb, chainpp, flags); } -unsigned char *smb_ParseStringCch(smb_packet_t * pktp, unsigned char * inp, - size_t cch, char ** chainpp, int flags) +clientchar_t *smb_ParseStringCch(smb_packet_t * pktp, unsigned char * inp, + size_t cch, char ** chainpp, int flags) { size_t cb = cch; @@ -2460,15 +2487,15 @@ unsigned char *smb_ParseStringCch(smb_packet_t * pktp, unsigned char * inp, return smb_ParseStringBuf(pktp->data, &pktp->stringsp, inp, &cb, chainpp, flags); } -unsigned char *smb_ParseStringBuf(const unsigned char * bufbase, - cm_space_t ** stringspp, - unsigned char *inp, size_t *pcb_max, - char **chainpp, int flags) +clientchar_t * +smb_ParseStringBuf(const char * bufbase, + cm_space_t ** stringspp, + unsigned char *inp, size_t *pcb_max, + char **chainpp, int flags) { #ifdef SMB_UNICODE if (!(flags & SMB_STRF_FORCEASCII)) { size_t cch_src; - int cb_dest; cm_space_t * spacep; int null_terms = 0; @@ -2499,85 +2526,62 @@ unsigned char *smb_ParseStringBuf(const unsigned char * bufbase, *chainpp = inp + sizeof(wchar_t); } - spacep->data[0] = '\0'; - return spacep->data; + *(spacep->wdata) = 0; + return spacep->wdata; } - cb_dest = cm_NormalizeUtf16StringToUtf8((const wchar_t *) inp, cch_src, - spacep->data, sizeof(spacep->data)); - if (cb_dest == 0) { - *stringspp = spacep->nextp; - cm_FreeSpace(spacep); -#ifdef DEBUG_UNICODE - DebugBreak(); -#endif - return NULL; - } + StringCchCopyNW(spacep->wdata, + lengthof(spacep->wdata), + (const clientchar_t *) inp, cch_src); if (chainpp) *chainpp = inp + (cch_src + null_terms)*sizeof(wchar_t); - if (cb_dest == 0) { -#ifdef DEBUG_UNICODE - DebugBreak(); -#endif - } else if (spacep->data[cb_dest - 1] != 0) { - spacep->data[cb_dest++] = 0; - } - - return spacep->data; + return spacep->wdata; } else { #endif + cm_space_t * spacep; + int cchdest; + /* Not using Unicode */ - if (chainpp) { + if (chainpp) { *chainpp = inp + strlen(inp) + 1; - } - if ((flags & SMB_STRF_ANSIPATH) && smb_StoreAnsiFilenames) - OemToChar(inp, inp); - return inp; + } + + spacep = cm_GetSpace(); + spacep->nextp = *stringspp; + *stringspp = spacep; + + cchdest = lengthof(spacep->wdata); + cm_Utf8ToUtf16(inp, *pcb_max, spacep->wdata, cchdest); + + return spacep->wdata; #ifdef SMB_UNICODE } #endif } unsigned char * smb_UnparseString(smb_packet_t * pktp, unsigned char * outp, - unsigned char * str, - size_t * plen, int flags) + clientchar_t * str, + size_t * plen, int flags) { size_t buffersize; int align = 0; if (outp == NULL) { /* we are only calculating the required size */ -#ifdef SMB_UNICODE - - if (WANTS_UNICODE(pktp) && !(flags & SMB_STRF_FORCEASCII)) { - int nchars; - nchars = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, - str, -1, NULL, 0); - if (nchars == 0 && GetLastError() == ERROR_NO_UNICODE_TRANSLATION) { + if (plen == NULL) + return NULL; - if ((flags & SMB_STRF_ANSIPATH) && smb_StoreAnsiFilenames) - nchars = MultiByteToWideChar(1252 /* ANSI - Latin1 */, - 0, str, -1, NULL, 0); - else - nchars = MultiByteToWideChar(CP_OEMCP, - 0, str, -1, NULL, 0); - } +#ifdef SMB_UNICODE - if (nchars == 0) { - osi_Log2(smb_logp, "UnparseString: Can't convert string to Unicode [%S], GLE=%d", - osi_LogSaveString(smb_logp, str), - GetLastError()); - if (plen) - *plen = 0; - return NULL; - } + if (WANTS_UNICODE(pktp) && !(flags & SMB_STRF_FORCEASCII)) { - if (plen) - *plen = sizeof(wchar_t) * ((flags & SMB_STRF_IGNORENULL)? nchars - 1 : nchars); + StringCbLengthW(str, SMB_STRINGBUFSIZE * sizeof(wchar_t), plen); + if (!(flags & SMB_STRF_IGNORENULL)) + *plen += sizeof(wchar_t); return (unsigned char *) 1; /* return TRUE if we are using unicode */ } @@ -2585,17 +2589,31 @@ unsigned char * smb_UnparseString(smb_packet_t * pktp, unsigned char * outp, #endif { /* Storing ANSI */ - size_t len; - len = strlen(str); + int cch_str; + int cch_dest; + + cch_str = cm_ClientStrLen(str); + cch_dest = cm_ClientStringToUtf8(str, cch_str, NULL, 0); + if (plen) - *plen = ((flags & SMB_STRF_IGNORENULL)? len: len+1); + *plen = ((flags & SMB_STRF_IGNORENULL)? cch_dest: cch_dest+1); return NULL; } + + /* Not reached. */ } - /* Number of bytes left in the buffer. */ + /* if outp != NULL ... */ + + /* Number of bytes left in the buffer. + + If outp lies inside the packet data buffer, we assume that the + buffer is the packet data buffer. Otherwise we assume that the + buffer is sizeof(packet->data). + + */ if (outp >= pktp->data && outp < pktp->data + sizeof(pktp->data)) { align = ((outp - pktp->data) % 2); buffersize = (pktp->data + sizeof(pktp->data)) - ((char *) outp); @@ -2612,7 +2630,7 @@ unsigned char * smb_UnparseString(smb_packet_t * pktp, unsigned char * outp, if (align) *outp++ = '\0'; - if (*str == '\0') { + if (*str == _C('\0')) { if (buffersize < sizeof(wchar_t)) return NULL; @@ -2623,29 +2641,10 @@ unsigned char * smb_UnparseString(smb_packet_t * pktp, unsigned char * outp, return outp + sizeof(wchar_t); } - nchars = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, - str, -1, (wchar_t *) outp, buffersize); - if (nchars == 0 && GetLastError() == ERROR_NO_UNICODE_TRANSLATION) { - - /* If we failed to translate the string from UTF-8 to - UTF-16, then chances are the string wasn't UTF-8 to - begin with. If StoreAnsiFileNames is set and this is - possibly an ANSI file name, we try assuming that the - source name is in ANSI. otherwise we try OEM. */ - - if ((flags & SMB_STRF_ANSIPATH) && smb_StoreAnsiFilenames) - nchars = MultiByteToWideChar(1252 /* ANSI - Latin1 */, - 0, str, -1, (wchar_t *) outp, buffersize); - else - nchars = MultiByteToWideChar(CP_OEMCP, - 0, str, -1, (wchar_t *) outp, buffersize); - } - + nchars = cm_ClientStringToUtf16(str, -1, (wchar_t *) outp, buffersize / sizeof(wchar_t)); if (nchars == 0) { - /* Both 1252 and OEM should translate to Unicode without a - complaint. This is something else. */ osi_Log2(smb_logp, "UnparseString: Can't convert string to Unicode [%S], GLE=%d", - osi_LogSaveString(smb_logp, str), + osi_LogSaveClientString(smb_logp, str), GetLastError()); return NULL; } @@ -2659,17 +2658,14 @@ unsigned char * smb_UnparseString(smb_packet_t * pktp, unsigned char * outp, #endif { /* Storing ANSI */ - size_t len; + size_t cch_dest; - len = strlen(str); len++; - if (len > buffersize) - return NULL; + cch_dest = cm_ClientStringToUtf8(str, -1, outp, buffersize); - strcpy(outp, str); if (plen) - *plen += ((flags & SMB_STRF_IGNORENULL)? len - 1: len); + *plen += ((flags & SMB_STRF_IGNORENULL)? cch_dest - 1: cch_dest); - return outp + len; + return outp + cch_dest; } } @@ -3491,7 +3487,9 @@ long smb_ReceiveNegotiate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) datap = smb_GetSMBData(outp, NULL); memcpy(datap,vcp->encKey,MSV1_0_CHALLENGE_LENGTH); /* and the faux domain name */ - strcpy(datap + MSV1_0_CHALLENGE_LENGTH,smb_ServerDomainName); + cm_ClientStringToUtf8(smb_ServerDomainName, -1, + datap + MSV1_0_CHALLENGE_LENGTH, + sizeof(outp->data)/sizeof(char) - (datap - outp->data)); } else if ( smb_authType == SMB_AUTH_EXTENDED ) { void * secBlob; int secBlobLength; @@ -3553,7 +3551,9 @@ long smb_ReceiveNegotiate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) /* paste in a new encryption key */ memcpy(datap, vcp->encKey, MSV1_0_CHALLENGE_LENGTH); /* and the faux domain name */ - strcpy(datap + MSV1_0_CHALLENGE_LENGTH, smb_ServerDomainName); + cm_ClientStringToUtf8(smb_ServerDomainName, -1, + datap + MSV1_0_CHALLENGE_LENGTH, + sizeof(outp->data)/sizeof(char) - (datap - outp->data)); } else { smb_SetSMBParm(outp, 11, 0); /* encryption key length */ smb_SetSMBParm(outp, 12, 0); /* resvd */ @@ -3856,22 +3856,25 @@ long smb_ReceiveCoreTreeConnect(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t * smb_tid_t *tidp; smb_user_t *uidp; unsigned short newTid; - char shareName[AFSPATHMAX]; - char *sharePath; + clientchar_t shareName[AFSPATHMAX]; + clientchar_t *sharePath; int shareFound; - char *tp; - char *pathp; + clientchar_t *tp; + clientchar_t *pathp; cm_user_t *userp; osi_Log0(smb_logp, "SMB receive tree connect"); /* parse input parameters */ - tp = smb_GetSMBData(inp, NULL); - pathp = smb_ParseASCIIBlock(inp, tp, &tp, SMB_STRF_ANSIPATH); - tp = strrchr(pathp, '\\'); + { + char *tbp; + tbp = smb_GetSMBData(inp, NULL); + pathp = smb_ParseASCIIBlock(inp, tbp, &tbp, SMB_STRF_ANSIPATH); + } + tp = cm_ClientStrRChr(pathp, '\\'); if (!tp) return CM_ERROR_BADSMB; - strcpy(shareName, tp+1); + cm_ClientStrCpy(shareName, lengthof(shareName), tp+1); lock_ObtainMutex(&vcp->mx); newTid = vcp->tidCounter++; @@ -3906,10 +3909,10 @@ long smb_ReceiveCoreTreeConnect(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t * * Returns true if succeeds with a valid name, otherwise it does * its best, but returns false. */ -int smb_Get8Dot3MaskFromPath(unsigned char *maskp, unsigned char *pathp) +int smb_Get8Dot3MaskFromPath(clientchar_t *maskp, clientchar_t *pathp) { - char *tp; - char *up; + clientchar_t *tp; + clientchar_t *up; int i; int tc; int valid8Dot3; @@ -3922,7 +3925,7 @@ int smb_Get8Dot3MaskFromPath(unsigned char *maskp, unsigned char *pathp) maskp[11] = '\0'; /* find last backslash, or use whole thing if there is none */ - tp = strrchr(pathp, '\\'); + tp = cm_ClientStrRChr(pathp, '\\'); if (!tp) tp = pathp; else @@ -3967,17 +3970,17 @@ int smb_Get8Dot3MaskFromPath(unsigned char *maskp, unsigned char *pathp) /* unreachable */ } -int smb_Match8Dot3Mask(char *unixNamep, char *maskp) +int smb_Match8Dot3Mask(clientchar_t *unixNamep, clientchar_t *maskp) { - char umask[11]; + clientchar_t umask[11]; int valid; int i; - char tc1; - char tc2; - char *tp1; - char *tp2; + clientchar_t tc1; + clientchar_t tc2; + clientchar_t *tp1; + clientchar_t *tp2; - /* XXX redo this, calling smb_V3MatchMask with a converted mask */ + /* XXX redo this, calling cm_MatchMask with a converted mask */ valid = smb_Get8Dot3MaskFromPath(umask, unixNamep); if (!valid) @@ -3989,10 +3992,10 @@ int smb_Match8Dot3Mask(char *unixNamep, char *maskp) tp1 = umask; /* real name, in mask format */ tp2 = maskp; /* mask, in mask format */ for(i=0; i<11; i++) { - tc1 = *tp1++; /* char from real name */ - tc2 = *tp2++; /* char from mask */ - tc1 = (char) cm_foldUpper[(unsigned char)tc1]; - tc2 = (char) cm_foldUpper[(unsigned char)tc2]; + tc1 = *tp1++; /* clientchar_t from real name */ + tc2 = *tp2++; /* clientchar_t from mask */ + tc1 = (clientchar_t) cm_foldUpper[(clientchar_t)tc1]; + tc2 = (clientchar_t) cm_foldUpper[(clientchar_t)tc2]; if (tc1 == tc2) continue; if (tc2 == '?' && tc1 != ' ') @@ -4006,11 +4009,11 @@ int smb_Match8Dot3Mask(char *unixNamep, char *maskp) return 1; } -char *smb_FindMask(char *pathp) +clientchar_t *smb_FindMask(clientchar_t *pathp) { - char *tp; + clientchar_t *tp; - tp = strrchr(pathp, '\\'); /* find last slash */ + tp = cm_ClientStrRChr(pathp, '\\'); /* find last slash */ if (tp) return tp+1; /* skip the slash */ @@ -4024,9 +4027,9 @@ char *smb_FindMask(char *pathp) dispatch function.) */ long smb_ReceiveCoreSearchVolume(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - unsigned char *pathp; + clientchar_t *pathp; unsigned char *tp; - unsigned char mask[12]; + clientchar_t mask[12]; unsigned char *statBlockp; unsigned char initStatBlock[21]; int statLen; @@ -4035,10 +4038,10 @@ long smb_ReceiveCoreSearchVolume(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t /* pull pathname and stat block out of request */ tp = smb_GetSMBData(inp, NULL); - pathp = smb_ParseASCIIBlock(inp, tp, (char **) &tp, + pathp = smb_ParseASCIIBlock(inp, tp, &tp, SMB_STRF_ANSIPATH|SMB_STRF_FORCEASCII); osi_assertx(pathp != NULL, "null path"); - statBlockp = smb_ParseVblBlock(tp, (char **) &tp, &statLen); + statBlockp = smb_ParseVblBlock(tp, &tp, &statLen); osi_assertx(statBlockp != NULL, "null statBlock"); if (statLen == 0) { statBlockp = initStatBlock; @@ -4096,7 +4099,7 @@ long smb_ReceiveCoreSearchVolume(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t static long smb_ApplyDirListPatches(smb_dirListPatch_t **dirPatchespp, - char * tidPathp, char * relPathp, + clientchar_t * tidPathp, clientchar_t * relPathp, cm_user_t *userp, cm_req_t *reqp) { long code = 0; @@ -4107,14 +4110,15 @@ smb_ApplyDirListPatches(smb_dirListPatch_t **dirPatchespp, char attr; smb_dirListPatch_t *patchp; smb_dirListPatch_t *npatchp; - char path[AFSPATHMAX]; + clientchar_t path[AFSPATHMAX]; for (patchp = *dirPatchespp; patchp; patchp = (smb_dirListPatch_t *) osi_QNext(&patchp->q)) { dptr = patchp->dptr; - snprintf(path, AFSPATHMAX, "%s\\%s", relPathp ? relPathp : "", patchp->dep->name); + cm_ClientStrPrintfN(path, AFSPATHMAX, _C("%s\\%s"), + relPathp ? relPathp : _C(""), patchp->dep->name); reqp->relPathp = path; reqp->tidPathp = tidPathp; @@ -4183,9 +4187,9 @@ long smb_ReceiveCoreSearchDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *ou { int attribute; long nextCookie; - char *tp; + unsigned char *tp; long code = 0; - char *pathp; + clientchar_t *pathp; cm_dirEntry_t *dep = 0; int maxCount; smb_dirListPatch_t *dirListPatchesp; @@ -4206,10 +4210,7 @@ long smb_ReceiveCoreSearchDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *ou cm_pageHeader_t *pageHeaderp; cm_user_t *userp = NULL; int slotInPage; - char shortName[13]; - char *actualName; - char *shortNameEnd; - char mask[12]; + clientchar_t mask[12]; int returnedNames; long nextEntryCookie; int numDirChunks; /* # of 32 byte dir chunks in this entry */ @@ -4220,7 +4221,7 @@ long smb_ReceiveCoreSearchDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *ou int starPattern; int rootPath = 0; int caseFold; - char *tidPathp = 0; + clientchar_t *tidPathp = 0; cm_req_t req; cm_fid_t fid; int fileType; @@ -4258,8 +4259,8 @@ long smb_ReceiveCoreSearchDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *ou if (attribute & 0x8) return smb_ReceiveCoreSearchVolume(vcp, inp, outp); - osi_Log2(smb_logp, "SMB receive search dir count %d [%s]", - maxCount, osi_LogSaveString(smb_logp, pathp)); + osi_Log2(smb_logp, "SMB receive search dir count %d [%S]", + maxCount, osi_LogSaveClientString(smb_logp, pathp)); if (*pathp == 0) { /* null pathp, treat as root dir */ if (!(attribute & SMB_ATTR_DIRECTORY)) /* exclude dirs */ @@ -4284,8 +4285,8 @@ long smb_ReceiveCoreSearchDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *ou dsp = smb_FindDirSearch(inCookiep[12]); if (!dsp) { /* can't find dir search status; fatal error */ - osi_Log3(smb_logp, "SMB receive search dir bad cookie: cookie %d nextCookie %u [%s]", - inCookiep[12], nextCookie, osi_LogSaveString(smb_logp, pathp)); + osi_Log3(smb_logp, "SMB receive search dir bad cookie: cookie %d nextCookie %u [%S]", + inCookiep[12], nextCookie, osi_LogSaveClientString(smb_logp, pathp)); return CM_ERROR_BADFD; } attribute = dsp->attribute; @@ -4318,7 +4319,7 @@ long smb_ReceiveCoreSearchDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *ou code = 0; } else { spacep = inp->spacep; - smb_StripLastComponent(spacep->data, NULL, pathp); + smb_StripLastComponent(spacep->wdata, NULL, pathp); code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp); if (code) { lock_ReleaseMutex(&dsp->mx); @@ -4327,15 +4328,17 @@ long smb_ReceiveCoreSearchDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *ou smb_ReleaseDirSearch(dsp); return CM_ERROR_NOFILES; } - strcpy(dsp->tidPath, tidPathp ? tidPathp : "/"); - strcpy(dsp->relPath, spacep->data); + cm_ClientStrCpy(dsp->tidPath, lengthof(dsp->tidPath), tidPathp ? tidPathp : _C("/")); + cm_ClientStrCpy(dsp->relPath, lengthof(dsp->relPath), spacep->wdata); - code = cm_NameI(cm_data.rootSCachep, spacep->data, + code = cm_NameI(cm_data.rootSCachep, spacep->wdata, caseFold | CM_FLAG_FOLLOW, userp, tidPathp, &req, &scp); if (code == 0) { #ifdef DFS_SUPPORT if (scp->fileType == CM_SCACHETYPE_DFSLINK) { - int pnc = cm_VolStatus_Notify_DFS_Mapping(scp, tidPathp, spacep->data); + int pnc; + + pnc = cm_VolStatus_Notify_DFS_Mapping(scp, tidPathp, spacep->wdata); cm_ReleaseSCache(scp); lock_ReleaseMutex(&dsp->mx); cm_ReleaseUser(userp); @@ -4408,6 +4411,10 @@ long smb_ReceiveCoreSearchDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *ou code = 0; returnedNames = 0; while (1) { + clientchar_t *actualName; + clientchar_t shortName[13]; + clientchar_t *shortNameEnd; + /* make sure that curOffset.LowPart doesn't point to the first * 32 bytes in the 2nd through last dir page, and that it doesn't * point at the first 13 32-byte chunks in the first dir page, @@ -4562,15 +4569,16 @@ long smb_ReceiveCoreSearchDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *ou nextEntryCookie = curOffset.LowPart + (CM_DIR_CHUNKSIZE * numDirChunks); /* Compute 8.3 name if necessary */ - actualName = dep->name; + actualName = cm_FsStringToClientStringAlloc(dep->name, -1, NULL); if (dep->fid.vnode != 0 && !cm_Is8Dot3(actualName)) { - cm_Gen8Dot3Name(dep, shortName, &shortNameEnd); + free(actualName); + cm_Gen8Dot3NameInt(dep->name, &dep->fid, shortName, &shortNameEnd); actualName = shortName; } - osi_Log3(smb_logp, "SMB search dir vn %d name %s (%s)", - dep->fid.vnode, osi_LogSaveString(smb_logp, dep->name), - osi_LogSaveString(smb_logp, actualName)); + osi_Log3(smb_logp, "SMB search dir vn %d name %s (%S)", + dep->fid.vnode, osi_LogSaveString(smb_logp, dep->name), + osi_LogSaveClientString(smb_logp, actualName)); if (dep->fid.vnode != 0 && smb_Match8Dot3Mask(actualName, mask)) { /* this is one of the entries to use: it is not deleted @@ -4604,11 +4612,11 @@ long smb_ReceiveCoreSearchDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *ou *op++ = resByte; memcpy(op, mask, 11); op += 11; - *op++ = (char) dsp->cookie; /* they say it must be non-zero */ - *op++ = (char)(nextEntryCookie & 0xff); - *op++ = (char)((nextEntryCookie>>8) & 0xff); - *op++ = (char)((nextEntryCookie>>16) & 0xff); - *op++ = (char)((nextEntryCookie>>24) & 0xff); + *op++ = (unsigned char) dsp->cookie; /* they say it must be non-zero */ + *op++ = (unsigned char)(nextEntryCookie & 0xff); + *op++ = (unsigned char)((nextEntryCookie>>8) & 0xff); + *op++ = (unsigned char)((nextEntryCookie>>16) & 0xff); + *op++ = (unsigned char)((nextEntryCookie>>24) & 0xff); memcpy(op, &clientCookie, 4); op += 4; /* now we emit the attribute. This is sort of tricky, @@ -4649,7 +4657,7 @@ long smb_ReceiveCoreSearchDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *ou * it fits in 8.3 or the pattern wouldn't match, but it * never hurts to be sure. */ - strncpy(op, actualName, 13); + cm_ClientStringToUtf8(actualName, -1, op, 13); if (smb_StoreAnsiFilenames) CharToOem(op, op); /* This is a UCHAR field, which is ASCII even if Unicode @@ -4711,8 +4719,8 @@ long smb_ReceiveCoreSearchDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *ou */ temp -= 3; /* deduct vbl block info */ osi_assertx(temp == (43 * returnedNames), "unexpected data length"); - origOp[1] = (char)(temp & 0xff); - origOp[2] = (char)((temp>>8) & 0xff); + origOp[1] = (unsigned char)(temp & 0xff); + origOp[2] = (unsigned char)((temp>>8) & 0xff); if (returnedNames == 0) smb_DeleteDirSearch(dsp); smb_ReleaseDirSearch(dsp); @@ -4729,24 +4737,25 @@ long smb_ReceiveCoreSearchDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *ou */ long smb_ReceiveCoreCheckPath(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - char *pathp; + clientchar_t *pathp; long code = 0; cm_scache_t *rootScp; cm_scache_t *newScp; cm_user_t *userp; unsigned int attrs; int caseFold; - char *tidPathp; + clientchar_t *tidPathp; cm_req_t req; + char * pdata; cm_InitReq(&req); - pathp = smb_GetSMBData(inp, NULL); - pathp = smb_ParseASCIIBlock(inp, pathp, NULL, SMB_STRF_ANSIPATH); + pdata = smb_GetSMBData(inp, NULL); + pathp = smb_ParseASCIIBlock(inp, pdata, NULL, SMB_STRF_ANSIPATH); if (!pathp) return CM_ERROR_BADFD; - osi_Log1(smb_logp, "SMB receive check path %s", - osi_LogSaveString(smb_logp, pathp)); + osi_Log1(smb_logp, "SMB receive check path %S", + osi_LogSaveClientString(smb_logp, pathp)); rootScp = cm_data.rootSCachep; @@ -4810,7 +4819,7 @@ long smb_ReceiveCoreCheckPath(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *ou /* SMB_COM_SET_INFORMATION */ long smb_ReceiveCoreSetFileAttributes(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - char *pathp; + clientchar_t *pathp; long code = 0; cm_scache_t *rootScp; unsigned short attribute; @@ -4819,7 +4828,8 @@ long smb_ReceiveCoreSetFileAttributes(smb_vc_t *vcp, smb_packet_t *inp, smb_pack afs_uint32 dosTime; cm_user_t *userp; int caseFold; - char *tidPathp; + clientchar_t *tidPathp; + char * datap; cm_req_t req; cm_InitReq(&req); @@ -4828,8 +4838,8 @@ long smb_ReceiveCoreSetFileAttributes(smb_vc_t *vcp, smb_packet_t *inp, smb_pack attribute = smb_GetSMBParm(inp, 0); dosTime = smb_GetSMBParm(inp, 1) | (smb_GetSMBParm(inp, 2) << 16); - pathp = smb_GetSMBData(inp, NULL); - pathp = smb_ParseASCIIBlock(inp, pathp, NULL, SMB_STRF_ANSIPATH); + datap = smb_GetSMBData(inp, NULL); + pathp = smb_ParseASCIIBlock(inp, datap, NULL, SMB_STRF_ANSIPATH); if (!pathp) return CM_ERROR_BADSMB; @@ -4924,7 +4934,7 @@ long smb_ReceiveCoreSetFileAttributes(smb_vc_t *vcp, smb_packet_t *inp, smb_pack long smb_ReceiveCoreGetFileAttributes(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - char *pathp; + clientchar_t *pathp; long code = 0; cm_scache_t *rootScp; cm_scache_t *newScp, *dscp; @@ -4932,23 +4942,24 @@ long smb_ReceiveCoreGetFileAttributes(smb_vc_t *vcp, smb_packet_t *inp, smb_pack int attrs; cm_user_t *userp; int caseFold; - char *tidPathp; + clientchar_t *tidPathp; cm_space_t *spacep; - char *lastComp; + clientchar_t *lastComp; + char * datap; cm_req_t req; cm_InitReq(&req); - pathp = smb_GetSMBData(inp, NULL); - pathp = smb_ParseASCIIBlock(inp, pathp, NULL, SMB_STRF_ANSIPATH); + datap = smb_GetSMBData(inp, NULL); + pathp = smb_ParseASCIIBlock(inp, datap, NULL, SMB_STRF_ANSIPATH); if (!pathp) return CM_ERROR_BADSMB; if (*pathp == 0) /* null path */ - pathp = "\\"; + pathp = _C("\\"); - osi_Log1(smb_logp, "SMB receive getfile attributes path %s", - osi_LogSaveString(smb_logp, pathp)); + osi_Log1(smb_logp, "SMB receive getfile attributes path %S", + osi_LogSaveClientString(smb_logp, pathp)); rootScp = cm_data.rootSCachep; @@ -4981,16 +4992,17 @@ long smb_ReceiveCoreGetFileAttributes(smb_vc_t *vcp, smb_packet_t *inp, smb_pack * http://msdn.microsoft.com/library/en-us/shellcc/platform/shell/programmersguide/shell_basics/shell_basics_extending/custom.asp */ spacep = inp->spacep; - smb_StripLastComponent(spacep->data, &lastComp, pathp); + smb_StripLastComponent(spacep->wdata, &lastComp, pathp); #ifndef SPECIAL_FOLDERS - if (lastComp && cm_stricmp_utf8N(lastComp, "\\desktop.ini") == 0) { - code = cm_NameI(rootScp, spacep->data, + if (lastComp && cm_ClientStrCmpIA(lastComp, _C("\\desktop.ini")) == 0) { + code = cm_NameI(rootScp, spacep->wdata, caseFold | CM_FLAG_DIRSEARCH | CM_FLAG_FOLLOW, userp, tidPathp, &req, &dscp); if (code == 0) { #ifdef DFS_SUPPORT if (dscp->fileType == CM_SCACHETYPE_DFSLINK) { - int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp, spacep->data); + int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp, + spacep->wdata); if ( WANTS_DFS_PATHNAMES(inp) || pnc ) return CM_ERROR_PATH_NOT_COVERED; else @@ -5108,8 +5120,8 @@ long smb_ReceiveCoreTreeDisconnect(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_ long smb_ReceiveCoreOpen(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { smb_fid_t *fidp; - char *pathp; - char *lastNamep; + clientchar_t *pathp; + clientchar_t *lastNamep; int share; int attribute; long code = 0; @@ -5118,15 +5130,16 @@ long smb_ReceiveCoreOpen(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) afs_uint32 dosTime; int caseFold; cm_space_t *spacep; - char *tidPathp; + clientchar_t *tidPathp; + char * datap; cm_req_t req; cm_InitReq(&req); - pathp = smb_GetSMBData(inp, NULL); - pathp = smb_ParseASCIIBlock(inp, pathp, NULL, SMB_STRF_ANSIPATH); - - osi_Log1(smb_logp, "SMB receive open file [%s]", osi_LogSaveString(smb_logp, pathp)); + datap = smb_GetSMBData(inp, NULL); + pathp = smb_ParseASCIIBlock(inp, datap, NULL, SMB_STRF_ANSIPATH); + + osi_Log1(smb_logp, "SMB receive open file [%S]", osi_LogSaveClientString(smb_logp, pathp)); #ifdef DEBUG_VERBOSE { @@ -5142,8 +5155,8 @@ long smb_ReceiveCoreOpen(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) attribute = smb_GetSMBParm(inp, 1); spacep = inp->spacep; - smb_StripLastComponent(spacep->data, &lastNamep, pathp); - if (lastNamep && strcmp(lastNamep, SMB_IOCTL_FILENAME) == 0) { + smb_StripLastComponent(spacep->wdata, &lastNamep, pathp); + if (lastNamep && cm_ClientStrCmp(lastNamep, _C(SMB_IOCTL_FILENAME)) == 0) { /* special case magic file name for receiving IOCTL requests * (since IOCTL calls themselves aren't getting through). */ @@ -5259,7 +5272,7 @@ typedef struct smb_unlinkRock { cm_user_t *userp; cm_req_t *reqp; smb_vc_t *vcp; - char *maskp; /* pointer to the star pattern */ + clientchar_t *maskp; /* pointer to the star pattern */ int flags; int any; cm_dirEntryList_t * matches; @@ -5271,7 +5284,7 @@ int smb_UnlinkProc(cm_scache_t *dscp, cm_dirEntry_t *dep, void *vrockp, osi_hype smb_unlinkRock_t *rockp; int caseFold; int match; - char matchName[MAX_PATH]; + normchar_t matchName[MAX_PATH]; rockp = vrockp; @@ -5279,25 +5292,25 @@ int smb_UnlinkProc(cm_scache_t *dscp, cm_dirEntry_t *dep, void *vrockp, osi_hype if (!(rockp->vcp->flags & SMB_VCFLAG_USEV3)) caseFold |= CM_FLAG_8DOT3; - cm_NormalizeUtf8String(dep->name, -1, matchName, sizeof(matchName)/sizeof(char)); - match = smb_V3MatchMask(matchName, rockp->maskp, caseFold); + cm_FsStringToNormString(dep->name, -1, matchName, lengthof(matchName)); + match = cm_MatchMask(matchName, rockp->maskp, caseFold); if (!match && - (rockp->flags & SMB_MASKFLAG_TILDE) && - !cm_Is8Dot3(dep->name)) { + (rockp->flags & SMB_MASKFLAG_TILDE) && + !cm_Is8Dot3(matchName)) { cm_Gen8Dot3Name(dep, matchName, NULL); /* 8.3 matches are always case insensitive */ - match = smb_V3MatchMask(matchName, rockp->maskp, caseFold | CM_FLAG_CASEFOLD); + match = cm_MatchMask(matchName, rockp->maskp, caseFold | CM_FLAG_CASEFOLD); } if (match) { - osi_Log1(smb_logp, "Found match %s", - osi_LogSaveString(smb_logp, matchName)); + osi_Log1(smb_logp, "Found match %S", + osi_LogSaveClientString(smb_logp, matchName)); cm_DirEntryListAdd(dep->name, &rockp->matches); rockp->any = 1; /* If we made a case sensitive exact match, we might as well quit now. */ - if (!(rockp->flags & SMB_MASKFLAG_CASEFOLD) && !strcmp(matchName, rockp->maskp)) + if (!(rockp->flags & SMB_MASKFLAG_CASEFOLD) && !cm_ClientStrCmp(matchName, rockp->maskp)) code = CM_ERROR_STOPNOW; else code = 0; @@ -5312,16 +5325,16 @@ long smb_ReceiveCoreUnlink(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { int attribute; long code = 0; - char *pathp; - char *tp; + clientchar_t *pathp; + unsigned char *tp; cm_space_t *spacep; cm_scache_t *dscp; - char *lastNamep; + clientchar_t *lastNamep; smb_unlinkRock_t rock; cm_user_t *userp; osi_hyper_t thyper; int caseFold; - char *tidPathp; + clientchar_t *tidPathp; cm_req_t req; cm_InitReq(&req); @@ -5331,11 +5344,11 @@ long smb_ReceiveCoreUnlink(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) tp = smb_GetSMBData(inp, NULL); pathp = smb_ParseASCIIBlock(inp, tp, &tp, SMB_STRF_ANSIPATH); - osi_Log1(smb_logp, "SMB receive unlink %s", - osi_LogSaveString(smb_logp, pathp)); + osi_Log1(smb_logp, "SMB receive unlink %S", + osi_LogSaveClientString(smb_logp, pathp)); spacep = inp->spacep; - smb_StripLastComponent(spacep->data, &lastNamep, pathp); + smb_StripLastComponent(spacep->wdata, &lastNamep, pathp); userp = smb_GetUserFromVCP(vcp, inp); @@ -5346,7 +5359,7 @@ long smb_ReceiveCoreUnlink(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) cm_ReleaseUser(userp); return CM_ERROR_NOSUCHPATH; } - code = cm_NameI(cm_data.rootSCachep, spacep->data, caseFold, userp, tidPathp, + code = cm_NameI(cm_data.rootSCachep, spacep->wdata, caseFold, userp, tidPathp, &req, &dscp); if (code) { cm_ReleaseUser(userp); @@ -5355,7 +5368,7 @@ long smb_ReceiveCoreUnlink(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) #ifdef DFS_SUPPORT if (dscp->fileType == CM_SCACHETYPE_DFSLINK) { - int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp,spacep->data); + int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp, spacep->wdata); cm_ReleaseSCache(dscp); cm_ReleaseUser(userp); if ( WANTS_DFS_PATHNAMES(inp) || pnc ) @@ -5372,8 +5385,8 @@ long smb_ReceiveCoreUnlink(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) lastNamep++; rock.any = 0; - rock.maskp = smb_FindMask(pathp); - rock.flags = ((strchr(rock.maskp, '~') != NULL) ? SMB_MASKFLAG_TILDE : 0); + rock.maskp = cm_ClientStringToNormStringAlloc(smb_FindMask(pathp), -1, NULL); + rock.flags = ((cm_ClientStrChr(rock.maskp, '~') != NULL) ? SMB_MASKFLAG_TILDE : 0); thyper.LowPart = 0; thyper.HighPart = 0; @@ -5406,15 +5419,15 @@ long smb_ReceiveCoreUnlink(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) cm_dirEntryList_t * entry; for (entry = rock.matches; code == 0 && entry; entry = entry->nextp) { - char normalizedName[MAX_PATH]; + normchar_t normalizedName[MAX_PATH]; /* Note: entry->name is a non-normalized name */ osi_Log1(smb_logp, "Unlinking %s", osi_LogSaveString(smb_logp, entry->name)); - cm_NormalizeUtf8String(entry->name, -1, normalizedName, - sizeof(normalizedName)/sizeof(char)); + cm_FsStringToNormString(entry->name, -1, + normalizedName, lengthof(normalizedName)); code = cm_Unlink(dscp, entry->name, normalizedName, userp, &req); @@ -5431,22 +5444,24 @@ long smb_ReceiveCoreUnlink(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) cm_ReleaseSCache(dscp); + free(rock.maskp); + if (code == 0 && !rock.any) code = CM_ERROR_NOSUCHFILE; return code; } typedef struct smb_renameRock { - cm_scache_t *odscp; /* old dir */ - cm_scache_t *ndscp; /* new dir */ - cm_user_t *userp; /* user */ - cm_req_t *reqp; /* request struct */ - smb_vc_t *vcp; /* virtual circuit */ - char *maskp; /* pointer to star pattern of old file name */ - int flags; /* tilde, casefold, etc */ - char *newNamep; /* ptr to the new file's name */ - char oldName[MAX_PATH]; /* non-normalized name */ - char normalizedOldName[MAX_PATH]; /* normalized name */ + cm_scache_t *odscp; /* old dir */ + cm_scache_t *ndscp; /* new dir */ + cm_user_t *userp; /* user */ + cm_req_t *reqp; /* request struct */ + smb_vc_t *vcp; /* virtual circuit */ + normchar_t *maskp; /* pointer to star pattern of old file name */ + int flags; /* tilde, casefold, etc */ + clientchar_t *newNamep; /* ptr to the new file's name */ + fschar_t fsOldName[MAX_PATH]; /* raw FS name */ + clientchar_t clOldName[MAX_PATH]; /* client name */ int any; } smb_renameRock_t; @@ -5456,29 +5471,29 @@ int smb_RenameProc(cm_scache_t *dscp, cm_dirEntry_t *dep, void *vrockp, osi_hype smb_renameRock_t *rockp; int caseFold; int match; - char matchName[MAX_PATH]; + normchar_t matchName[MAX_PATH]; rockp = (smb_renameRock_t *) vrockp; - cm_NormalizeUtf8String(dep->name, -1, matchName, sizeof(matchName)/sizeof(char)); + cm_FsStringToNormString(dep->name, -1, matchName, lengthof(matchName)); caseFold = ((rockp->flags & SMB_MASKFLAG_CASEFOLD)? CM_FLAG_CASEFOLD : 0); if (!(rockp->vcp->flags & SMB_VCFLAG_USEV3)) caseFold |= CM_FLAG_8DOT3; - match = smb_V3MatchMask(matchName, rockp->maskp, caseFold); + match = cm_MatchMask(matchName, rockp->maskp, caseFold); if (!match && (rockp->flags & SMB_MASKFLAG_TILDE) && - !cm_Is8Dot3(dep->name)) { + !cm_Is8Dot3(matchName)) { cm_Gen8Dot3Name(dep, matchName, NULL); - match = smb_V3MatchMask(matchName, rockp->maskp, caseFold); + match = cm_MatchMask(matchName, rockp->maskp, caseFold); } if (match) { rockp->any = 1; - StringCbCopyA(rockp->oldName, sizeof(rockp->oldName), dep->name); - StringCbCopyA(rockp->normalizedOldName, sizeof(rockp->normalizedOldName), - matchName); - code = CM_ERROR_STOPNOW; + StringCbCopyA(rockp->fsOldName, sizeof(rockp->fsOldName), dep->name); + cm_ClientStrCpy(rockp->clOldName, lengthof(rockp->clOldName), + matchName); + code = CM_ERROR_STOPNOW; } else { code = 0; } @@ -5488,7 +5503,7 @@ int smb_RenameProc(cm_scache_t *dscp, cm_dirEntry_t *dep, void *vrockp, osi_hype long -smb_Rename(smb_vc_t *vcp, smb_packet_t *inp, char * oldPathp, char * newPathp, int attrs) +smb_Rename(smb_vc_t *vcp, smb_packet_t *inp, clientchar_t * oldPathp, clientchar_t * newPathp, int attrs) { long code = 0; cm_space_t *spacep = NULL; @@ -5497,12 +5512,12 @@ smb_Rename(smb_vc_t *vcp, smb_packet_t *inp, char * oldPathp, char * newPathp, i cm_scache_t *newDscp = NULL; cm_scache_t *tmpscp= NULL; cm_scache_t *tmpscp2 = NULL; - char *oldLastNamep; - char *newLastNamep; + clientchar_t *oldLastNamep; + clientchar_t *newLastNamep; osi_hyper_t thyper; cm_user_t *userp; int caseFold; - char *tidPathp; + clientchar_t *tidPathp; DWORD filter; cm_req_t req; @@ -5515,10 +5530,10 @@ smb_Rename(smb_vc_t *vcp, smb_packet_t *inp, char * oldPathp, char * newPathp, i cm_InitReq(&req); spacep = inp->spacep; - smb_StripLastComponent(spacep->data, &oldLastNamep, oldPathp); + smb_StripLastComponent(spacep->wdata, &oldLastNamep, oldPathp); caseFold = CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD; - code = cm_NameI(cm_data.rootSCachep, spacep->data, caseFold, + code = cm_NameI(cm_data.rootSCachep, spacep->wdata, caseFold, userp, tidPathp, &req, &oldDscp); if (code) { cm_ReleaseUser(userp); @@ -5527,7 +5542,7 @@ smb_Rename(smb_vc_t *vcp, smb_packet_t *inp, char * oldPathp, char * newPathp, i #ifdef DFS_SUPPORT if (oldDscp->fileType == CM_SCACHETYPE_DFSLINK) { - int pnc = cm_VolStatus_Notify_DFS_Mapping(oldDscp, tidPathp, spacep->data); + int pnc = cm_VolStatus_Notify_DFS_Mapping(oldDscp, tidPathp, spacep->wdata); cm_ReleaseSCache(oldDscp); cm_ReleaseUser(userp); if ( WANTS_DFS_PATHNAMES(inp) || pnc ) @@ -5537,8 +5552,8 @@ smb_Rename(smb_vc_t *vcp, smb_packet_t *inp, char * oldPathp, char * newPathp, i } #endif /* DFS_SUPPORT */ - smb_StripLastComponent(spacep->data, &newLastNamep, newPathp); - code = cm_NameI(cm_data.rootSCachep, spacep->data, caseFold, + smb_StripLastComponent(spacep->wdata, &newLastNamep, newPathp); + code = cm_NameI(cm_data.rootSCachep, spacep->wdata, caseFold, userp, tidPathp, &req, &newDscp); if (code) { @@ -5549,7 +5564,7 @@ smb_Rename(smb_vc_t *vcp, smb_packet_t *inp, char * oldPathp, char * newPathp, i #ifdef DFS_SUPPORT if (newDscp->fileType == CM_SCACHETYPE_DFSLINK) { - int pnc = cm_VolStatus_Notify_DFS_Mapping(newDscp, tidPathp, spacep->data); + int pnc = cm_VolStatus_Notify_DFS_Mapping(newDscp, tidPathp, spacep->wdata); cm_ReleaseSCache(oldDscp); cm_ReleaseSCache(newDscp); cm_ReleaseUser(userp); @@ -5585,11 +5600,11 @@ smb_Rename(smb_vc_t *vcp, smb_packet_t *inp, char * oldPathp, char * newPathp, i rock.userp = userp; rock.reqp = &req; rock.vcp = vcp; - rock.maskp = oldLastNamep; - rock.flags = ((strchr(oldLastNamep, '~') != NULL) ? SMB_MASKFLAG_TILDE : 0); + rock.maskp = cm_ClientStringToNormStringAlloc(oldLastNamep, -1, NULL); + rock.flags = ((cm_ClientStrChr(oldLastNamep, '~') != NULL) ? SMB_MASKFLAG_TILDE : 0); rock.newNamep = newLastNamep; - rock.oldName[0] = '\0'; - rock.normalizedOldName[0] = '\0'; + rock.fsOldName[0] = '\0'; + rock.clOldName[0] = '\0'; rock.any = 0; /* Check if the file already exists; if so return error */ @@ -5597,13 +5612,13 @@ smb_Rename(smb_vc_t *vcp, smb_packet_t *inp, char * oldPathp, char * newPathp, i if ((code != CM_ERROR_NOSUCHFILE) && (code != CM_ERROR_BPLUS_NOMATCH) && (code != CM_ERROR_NOSUCHPATH) && (code != CM_ERROR_NOSUCHVOLUME) ) { - osi_Log2(smb_logp, " lookup returns %ld for [%s]", code, - osi_LogSaveString(smb_logp, newLastNamep)); + osi_Log2(smb_logp, " lookup returns %ld for [%S]", code, + osi_LogSaveClientString(smb_logp, newLastNamep)); /* Check if the old and the new names differ only in case. If so return * success, else return CM_ERROR_EXISTS */ - if (!code && oldDscp == newDscp && !cm_stricmp_utf8(oldLastNamep, newLastNamep)) { + if (!code && oldDscp == newDscp && !cm_ClientStrCmpI(oldLastNamep, newLastNamep)) { /* This would be a success only if the old file is *as same as* the new file */ code = cm_Lookup(oldDscp, oldLastNamep, CM_FLAG_CHECKPATH, userp, &req, &tmpscp2); @@ -5628,6 +5643,9 @@ smb_Rename(smb_vc_t *vcp, smb_packet_t *inp, char * oldPathp, char * newPathp, i cm_ReleaseSCache(newDscp); cm_ReleaseSCache(oldDscp); cm_ReleaseUser(userp); + + free(rock.maskp); + rock.maskp = NULL; return code; } @@ -5644,10 +5662,10 @@ smb_Rename(smb_vc_t *vcp, smb_packet_t *inp, char * oldPathp, char * newPathp, i } osi_Log1(smb_logp, "smb_RenameProc returns %ld", code); - if (code == CM_ERROR_STOPNOW && rock.oldName[0] != '\0') { - code = cm_Rename(rock.odscp, rock.oldName, rock.normalizedOldName, + if (code == CM_ERROR_STOPNOW && rock.fsOldName[0] != '\0') { + code = cm_Rename(rock.odscp, rock.fsOldName, rock.clOldName, rock.ndscp, rock.newNamep, rock.userp, - rock.reqp); + rock.reqp); /* if the call worked, stop doing the search now, since we * really only want to rename one file. */ @@ -5666,17 +5684,17 @@ smb_Rename(smb_vc_t *vcp, smb_packet_t *inp, char * oldPathp, char * newPathp, i if (oldDscp == newDscp) { if (oldDscp->flags & CM_SCACHEFLAG_ANYWATCH) smb_NotifyChange(FILE_ACTION_RENAMED_OLD_NAME, - filter, oldDscp, rock.normalizedOldName, - newLastNamep, TRUE); + filter, oldDscp, rock.clOldName, + newLastNamep, TRUE); } else { if (oldDscp->flags & CM_SCACHEFLAG_ANYWATCH) smb_NotifyChange(FILE_ACTION_RENAMED_OLD_NAME, - filter, oldDscp, rock.normalizedOldName, + filter, oldDscp, rock.clOldName, NULL, TRUE); if (newDscp->flags & CM_SCACHEFLAG_ANYWATCH) smb_NotifyChange(FILE_ACTION_RENAMED_NEW_NAME, - filter, newDscp, newLastNamep, - NULL, TRUE); + filter, newDscp, newLastNamep, + NULL, TRUE); } } @@ -5685,11 +5703,15 @@ smb_Rename(smb_vc_t *vcp, smb_packet_t *inp, char * oldPathp, char * newPathp, i cm_ReleaseUser(userp); cm_ReleaseSCache(oldDscp); cm_ReleaseSCache(newDscp); + + free(rock.maskp); + rock.maskp = NULL; + return code; } long -smb_Link(smb_vc_t *vcp, smb_packet_t *inp, char * oldPathp, char * newPathp) +smb_Link(smb_vc_t *vcp, smb_packet_t *inp, clientchar_t * oldPathp, clientchar_t * newPathp) { long code = 0; cm_space_t *spacep = NULL; @@ -5698,11 +5720,11 @@ smb_Link(smb_vc_t *vcp, smb_packet_t *inp, char * oldPathp, char * newPathp) cm_scache_t *tmpscp= NULL; cm_scache_t *tmpscp2 = NULL; cm_scache_t *sscp = NULL; - char *oldLastNamep; - char *newLastNamep; + clientchar_t *oldLastNamep; + clientchar_t *newLastNamep; cm_user_t *userp; int caseFold; - char *tidPathp; + clientchar_t *tidPathp; DWORD filter; cm_req_t req; @@ -5719,9 +5741,9 @@ smb_Link(smb_vc_t *vcp, smb_packet_t *inp, char * oldPathp, char * newPathp) caseFold = CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD; spacep = inp->spacep; - smb_StripLastComponent(spacep->data, &oldLastNamep, oldPathp); + smb_StripLastComponent(spacep->wdata, &oldLastNamep, oldPathp); - code = cm_NameI(cm_data.rootSCachep, spacep->data, caseFold, + code = cm_NameI(cm_data.rootSCachep, spacep->wdata, caseFold, userp, tidPathp, &req, &oldDscp); if (code) { cm_ReleaseUser(userp); @@ -5730,7 +5752,7 @@ smb_Link(smb_vc_t *vcp, smb_packet_t *inp, char * oldPathp, char * newPathp) #ifdef DFS_SUPPORT if (oldDscp->fileType == CM_SCACHETYPE_DFSLINK) { - int pnc = cm_VolStatus_Notify_DFS_Mapping(oldDscp, tidPathp, spacep->data); + int pnc = cm_VolStatus_Notify_DFS_Mapping(oldDscp, tidPathp, spacep->wdata); cm_ReleaseSCache(oldDscp); cm_ReleaseUser(userp); if ( WANTS_DFS_PATHNAMES(inp) || pnc ) @@ -5740,8 +5762,8 @@ smb_Link(smb_vc_t *vcp, smb_packet_t *inp, char * oldPathp, char * newPathp) } #endif /* DFS_SUPPORT */ - smb_StripLastComponent(spacep->data, &newLastNamep, newPathp); - code = cm_NameI(cm_data.rootSCachep, spacep->data, caseFold, + smb_StripLastComponent(spacep->wdata, &newLastNamep, newPathp); + code = cm_NameI(cm_data.rootSCachep, spacep->wdata, caseFold, userp, tidPathp, &req, &newDscp); if (code) { cm_ReleaseSCache(oldDscp); @@ -5751,7 +5773,7 @@ smb_Link(smb_vc_t *vcp, smb_packet_t *inp, char * oldPathp, char * newPathp) #ifdef DFS_SUPPORT if (newDscp->fileType == CM_SCACHETYPE_DFSLINK) { - int pnc = cm_VolStatus_Notify_DFS_Mapping(newDscp, tidPathp, spacep->data); + int pnc = cm_VolStatus_Notify_DFS_Mapping(newDscp, tidPathp, spacep->wdata); cm_ReleaseSCache(newDscp); cm_ReleaseSCache(oldDscp); cm_ReleaseUser(userp); @@ -5785,7 +5807,7 @@ smb_Link(smb_vc_t *vcp, smb_packet_t *inp, char * oldPathp, char * newPathp) newLastNamep++; /* now lookup the old name */ - osi_Log1(smb_logp," looking up [%s]", osi_LogSaveString(smb_logp,oldLastNamep)); + osi_Log1(smb_logp," looking up [%S]", osi_LogSaveClientString(smb_logp,oldLastNamep)); code = cm_Lookup(oldDscp, oldLastNamep, CM_FLAG_CHECKPATH | CM_FLAG_CASEFOLD, userp, &req, &sscp); if (code) { cm_ReleaseSCache(oldDscp); @@ -5799,8 +5821,8 @@ smb_Link(smb_vc_t *vcp, smb_packet_t *inp, char * oldPathp, char * newPathp) if ((code != CM_ERROR_NOSUCHFILE) && (code != CM_ERROR_BPLUS_NOMATCH) && (code != CM_ERROR_NOSUCHPATH) && (code != CM_ERROR_NOSUCHVOLUME) ) { - osi_Log2(smb_logp, " lookup returns %ld for [%s]", code, - osi_LogSaveString(smb_logp, newLastNamep)); + osi_Log2(smb_logp, " lookup returns %ld for [%S]", code, + osi_LogSaveClientString(smb_logp, newLastNamep)); /* if the existing link is to the same file, then we return success */ if (!code) { @@ -5822,7 +5844,7 @@ smb_Link(smb_vc_t *vcp, smb_packet_t *inp, char * oldPathp, char * newPathp) } /* now create the hardlink */ - osi_Log1(smb_logp," Attempting to create new link [%s]", osi_LogSaveString(smb_logp, newLastNamep)); + osi_Log1(smb_logp," Attempting to create new link [%S]", osi_LogSaveClientString(smb_logp, newLastNamep)); code = cm_Link(newDscp, newLastNamep, sscp, 0, userp, &req); osi_Log1(smb_logp," Link returns 0x%x", code); @@ -5848,18 +5870,18 @@ smb_Link(smb_vc_t *vcp, smb_packet_t *inp, char * oldPathp, char * newPathp) long smb_ReceiveCoreRename(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - char *oldPathp; - char *newPathp; - char *tp; + clientchar_t *oldPathp; + clientchar_t *newPathp; + unsigned char *tp; long code; tp = smb_GetSMBData(inp, NULL); oldPathp = smb_ParseASCIIBlock(inp, tp, &tp, SMB_STRF_ANSIPATH); newPathp = smb_ParseASCIIBlock(inp, tp, &tp, SMB_STRF_ANSIPATH); - osi_Log2(smb_logp, "smb rename [%s] to [%s]", - osi_LogSaveString(smb_logp, oldPathp), - osi_LogSaveString(smb_logp, newPathp)); + osi_Log2(smb_logp, "smb rename [%S] to [%S]", + osi_LogSaveClientString(smb_logp, oldPathp), + osi_LogSaveClientString(smb_logp, newPathp)); code = smb_Rename(vcp,inp,oldPathp,newPathp,0); @@ -5873,7 +5895,7 @@ typedef struct smb_rmdirRock { cm_scache_t *dscp; cm_user_t *userp; cm_req_t *reqp; - char *maskp; /* pointer to the star pattern */ + normchar_t *maskp; /* pointer to the star pattern */ int flags; int any; cm_dirEntryList_t * matches; @@ -5884,24 +5906,24 @@ int smb_RmdirProc(cm_scache_t *dscp, cm_dirEntry_t *dep, void *vrockp, osi_hyper long code = 0; smb_rmdirRock_t *rockp; int match; - char matchName[MAX_PATH]; + normchar_t matchName[MAX_PATH]; rockp = (smb_rmdirRock_t *) vrockp; - cm_NormalizeUtf8String(dep->name, -1, matchName, sizeof(matchName)/sizeof(char)); + cm_FsStringToNormString(dep->name, -1, matchName, lengthof(matchName)); if (rockp->flags & SMB_MASKFLAG_CASEFOLD) - match = (cm_stricmp_utf8(matchName, rockp->maskp) == 0); + match = (cm_ClientStrCmpI(matchName, rockp->maskp) == 0); else - match = (strcmp(matchName, rockp->maskp) == 0); + match = (cm_ClientStrCmp(matchName, rockp->maskp) == 0); if (!match && (rockp->flags & SMB_MASKFLAG_TILDE) && - !cm_Is8Dot3(dep->name)) { + !cm_Is8Dot3(matchName)) { cm_Gen8Dot3Name(dep, matchName, NULL); - match = (cm_stricmp_utf8(matchName, rockp->maskp) == 0); + match = (cm_ClientStrCmpI(matchName, rockp->maskp) == 0); } if (match) { - rockp->any = 1; + rockp->any = 1; cm_DirEntryListAdd(dep->name, &rockp->matches); } @@ -5912,16 +5934,16 @@ int smb_RmdirProc(cm_scache_t *dscp, cm_dirEntry_t *dep, void *vrockp, osi_hyper long smb_ReceiveCoreRemoveDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { long code = 0; - char *pathp; - char *tp; + clientchar_t *pathp; + unsigned char *tp; cm_space_t *spacep; cm_scache_t *dscp; - char *lastNamep; + clientchar_t *lastNamep; smb_rmdirRock_t rock; cm_user_t *userp; osi_hyper_t thyper; int caseFold; - char *tidPathp; + clientchar_t *tidPathp; cm_req_t req; cm_InitReq(&req); @@ -5930,7 +5952,7 @@ long smb_ReceiveCoreRemoveDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *ou pathp = smb_ParseASCIIBlock(inp, tp, &tp, SMB_STRF_ANSIPATH); spacep = inp->spacep; - smb_StripLastComponent(spacep->data, &lastNamep, pathp); + smb_StripLastComponent(spacep->wdata, &lastNamep, pathp); userp = smb_GetUserFromVCP(vcp, inp); @@ -5941,7 +5963,7 @@ long smb_ReceiveCoreRemoveDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *ou cm_ReleaseUser(userp); return CM_ERROR_NOSUCHPATH; } - code = cm_NameI(cm_data.rootSCachep, spacep->data, caseFold | CM_FLAG_FOLLOW, + code = cm_NameI(cm_data.rootSCachep, spacep->wdata, caseFold | CM_FLAG_FOLLOW, userp, tidPathp, &req, &dscp); if (code) { @@ -5951,7 +5973,7 @@ long smb_ReceiveCoreRemoveDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *ou #ifdef DFS_SUPPORT if (dscp->fileType == CM_SCACHETYPE_DFSLINK) { - int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp, spacep->data); + int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp, spacep->wdata); cm_ReleaseSCache(dscp); cm_ReleaseUser(userp); if ( WANTS_DFS_PATHNAMES(inp) || pnc ) @@ -5968,8 +5990,8 @@ long smb_ReceiveCoreRemoveDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *ou lastNamep++; rock.any = 0; - rock.maskp = lastNamep; - rock.flags = ((strchr(rock.maskp, '~') != NULL) ? SMB_MASKFLAG_TILDE : 0); + rock.maskp = cm_ClientStringToNormStringAlloc(lastNamep, -1, NULL); + rock.flags = ((cm_ClientStrChr(rock.maskp, '~') != NULL) ? SMB_MASKFLAG_TILDE : 0); thyper.LowPart = 0; thyper.HighPart = 0; @@ -5991,20 +6013,19 @@ long smb_ReceiveCoreRemoveDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *ou cm_dirEntryList_t * entry; for (entry = rock.matches; code == 0 && entry; entry = entry->nextp) { - char normalizedName[MAX_PATH]; + clientchar_t clientName[MAX_PATH]; - cm_NormalizeUtf8String(entry->name, -1, normalizedName, - sizeof(normalizedName)/sizeof(char)); + cm_FsStringToClientString(entry->name, -1, clientName, lengthof(clientName)); osi_Log1(smb_logp, "Removing directory %s", osi_LogSaveString(smb_logp, entry->name)); - code = cm_RemoveDir(dscp, entry->name, normalizedName, userp, &req); + code = cm_RemoveDir(dscp, entry->name, clientName, userp, &req); if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH)) smb_NotifyChange(FILE_ACTION_REMOVED, FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_CREATION, - dscp, normalizedName, NULL, TRUE); + dscp, clientName, NULL, TRUE); } } @@ -6016,6 +6037,10 @@ long smb_ReceiveCoreRemoveDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *ou if (code == 0 && !rock.any) code = CM_ERROR_NOSUCHFILE; + + free(rock.maskp); + rock.maskp = NULL; + return code; } @@ -6075,45 +6100,45 @@ long smb_ReceiveCoreFlush(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) } struct smb_FullNameRock { - char *name; - cm_scache_t *vnode; - char *fullName; - char *originalName; + clientchar_t *name; + cm_scache_t *vnode; + clientchar_t *fullName; + fschar_t *originalName; }; int smb_FullNameProc(cm_scache_t *scp, cm_dirEntry_t *dep, void *rockp, osi_hyper_t *offp) { - char matchName[MAX_PATH]; + normchar_t matchName[MAX_PATH]; struct smb_FullNameRock *vrockp; vrockp = (struct smb_FullNameRock *)rockp; - cm_NormalizeUtf8String(dep->name, -1, matchName, sizeof(matchName)/sizeof(char)); + cm_FsStringToNormString(dep->name, -1, matchName, lengthof(matchName)); - if (!cm_Is8Dot3(dep->name)) { - char shortName[13]; + if (!cm_Is8Dot3(matchName)) { + clientchar_t shortName[13]; cm_Gen8Dot3Name(dep, shortName, NULL); - if (cm_stricmp_utf8N(shortName, vrockp->name) == 0) { - vrockp->fullName = strdup(matchName); - vrockp->originalName = strdup(dep->name); + if (cm_ClientStrCmpIA(shortName, vrockp->name) == 0) { + vrockp->fullName = cm_ClientStrDup(matchName); + vrockp->originalName = cm_FsStrDup(dep->name); return CM_ERROR_STOPNOW; } } - if (cm_stricmp_utf8(matchName, vrockp->name) == 0 && + if (cm_ClientStrCmpI(matchName, vrockp->name) == 0 && ntohl(dep->fid.vnode) == vrockp->vnode->fid.vnode && ntohl(dep->fid.unique) == vrockp->vnode->fid.unique) { - vrockp->fullName = strdup(matchName); - vrockp->originalName = strdup(dep->name); + vrockp->fullName = cm_ClientStrDup(matchName); + vrockp->originalName = cm_FsStrDup(dep->name); return CM_ERROR_STOPNOW; } return 0; } -void smb_FullName(cm_scache_t *dscp, cm_scache_t *scp, char *pathp, - char **newPathp, char ** originalPathp, +void smb_FullName(cm_scache_t *dscp, cm_scache_t *scp, clientchar_t *pathp, + clientchar_t **newPathp, fschar_t ** originalPathp, cm_user_t *userp, cm_req_t *reqp) { struct smb_FullNameRock rock; @@ -6128,8 +6153,8 @@ void smb_FullName(cm_scache_t *dscp, cm_scache_t *scp, char *pathp, *newPathp = rock.fullName; *originalPathp = rock.originalName; } else { - *newPathp = strdup(pathp); - *originalPathp = strdup(pathp); + *newPathp = cm_ClientStrDup(pathp); + *originalPathp = cm_ClientStringToFsStringAlloc(pathp, -1, NULL); } } @@ -6138,7 +6163,7 @@ long smb_CloseFID(smb_vc_t *vcp, smb_fid_t *fidp, cm_user_t *userp, long code = 0; cm_req_t req; cm_scache_t *dscp = NULL; - char *pathp = NULL; + clientchar_t *pathp = NULL; cm_scache_t * scp = NULL; cm_scache_t *delscp = NULL; int nullcreator = 0; @@ -6177,7 +6202,7 @@ long smb_CloseFID(smb_vc_t *vcp, smb_fid_t *fidp, cm_user_t *userp, } if (fidp->NTopen_pathp) { - pathp = strdup(fidp->NTopen_pathp); + pathp = cm_ClientStrDup(fidp->NTopen_pathp); } if (fidp->scp) { @@ -6246,8 +6271,8 @@ long smb_CloseFID(smb_vc_t *vcp, smb_fid_t *fidp, cm_user_t *userp, } if (fidp->flags & SMB_FID_DELONCLOSE) { - char *fullPathp = NULL; - char *originalNamep = NULL; + clientchar_t *fullPathp = NULL; + fschar_t *originalNamep = NULL; lock_ReleaseMutex(&fidp->mx); @@ -6276,7 +6301,7 @@ long smb_CloseFID(smb_vc_t *vcp, smb_fid_t *fidp, cm_user_t *userp, } if (fullPathp) - free(fullPathp); + free(fullPathp); if (originalNamep) free(originalNamep); @@ -7283,18 +7308,18 @@ long smb_ReceiveCoreRead(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) /* SMB_COM_CREATE_DIRECTORY */ long smb_ReceiveCoreMakeDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - char *pathp; + clientchar_t *pathp; long code = 0; cm_space_t *spacep; - char *tp; + unsigned char *tp; cm_user_t *userp; cm_scache_t *dscp; /* dir we're dealing with */ cm_scache_t *scp; /* file we're creating */ cm_attr_t setAttr; int initialModeBits; - char *lastNamep; + clientchar_t *lastNamep; int caseFold; - char *tidPathp; + clientchar_t *tidPathp; cm_req_t req; cm_InitReq(&req); @@ -7307,11 +7332,11 @@ long smb_ReceiveCoreMakeDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp tp = smb_GetSMBData(inp, NULL); pathp = smb_ParseASCIIBlock(inp, tp, &tp, SMB_STRF_ANSIPATH); - if (strcmp(pathp, "\\") == 0) + if (cm_ClientStrCmp(pathp, _C("\\")) == 0) return CM_ERROR_EXISTS; spacep = inp->spacep; - smb_StripLastComponent(spacep->data, &lastNamep, pathp); + smb_StripLastComponent(spacep->wdata, &lastNamep, pathp); userp = smb_GetUserFromVCP(vcp, inp); @@ -7323,7 +7348,7 @@ long smb_ReceiveCoreMakeDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp return CM_ERROR_NOSUCHPATH; } - code = cm_NameI(cm_data.rootSCachep, spacep->data, + code = cm_NameI(cm_data.rootSCachep, spacep->wdata, caseFold | CM_FLAG_FOLLOW | CM_FLAG_CHECKPATH, userp, tidPathp, &req, &dscp); @@ -7334,7 +7359,7 @@ long smb_ReceiveCoreMakeDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp #ifdef DFS_SUPPORT if (dscp->fileType == CM_SCACHETYPE_DFSLINK) { - int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp, spacep->data); + int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp, spacep->wdata); cm_ReleaseSCache(dscp); cm_ReleaseUser(userp); if ( WANTS_DFS_PATHNAMES(inp) || pnc ) @@ -7384,7 +7409,7 @@ long smb_ReceiveCoreMakeDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp return 0; } -BOOL smb_IsLegalFilename(char *filename) +BOOL smb_IsLegalFilename(clientchar_t *filename) { /* * Find the longest substring of filename that does not contain @@ -7392,19 +7417,19 @@ BOOL smb_IsLegalFilename(char *filename) * than the length of the whole string, then one or more of the * illegal chars is in filename. */ - if (strcspn(filename, illegalChars) < strlen(filename)) + if (cm_ClientStrCSpn(filename, illegalChars) < cm_ClientStrLen(filename)) return FALSE; return TRUE; -} +} /* SMB_COM_CREATE and SMB_COM_CREATE_NEW */ long smb_ReceiveCoreCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - char *pathp; + clientchar_t *pathp; long code = 0; cm_space_t *spacep; - char *tp; + unsigned char *tp; int excl; cm_user_t *userp; cm_scache_t *dscp; /* dir we're dealing with */ @@ -7413,10 +7438,10 @@ long smb_ReceiveCoreCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) int initialModeBits; smb_fid_t *fidp; int attributes; - char *lastNamep; + clientchar_t *lastNamep; int caseFold; afs_uint32 dosTime; - char *tidPathp; + clientchar_t *tidPathp; cm_req_t req; int created = 0; /* the file was new */ @@ -7437,7 +7462,7 @@ long smb_ReceiveCoreCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) pathp = smb_ParseASCIIBlock(inp, tp, &tp, SMB_STRF_ANSIPATH); spacep = inp->spacep; - smb_StripLastComponent(spacep->data, &lastNamep, pathp); + smb_StripLastComponent(spacep->wdata, &lastNamep, pathp); userp = smb_GetUserFromVCP(vcp, inp); @@ -7448,7 +7473,7 @@ long smb_ReceiveCoreCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) cm_ReleaseUser(userp); return CM_ERROR_NOSUCHPATH; } - code = cm_NameI(cm_data.rootSCachep, spacep->data, caseFold | CM_FLAG_FOLLOW, + code = cm_NameI(cm_data.rootSCachep, spacep->wdata, caseFold | CM_FLAG_FOLLOW, userp, tidPathp, &req, &dscp); if (code) { @@ -7458,7 +7483,7 @@ long smb_ReceiveCoreCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) #ifdef DFS_SUPPORT if (dscp->fileType == CM_SCACHETYPE_DFSLINK) { - int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp, spacep->data); + int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp, spacep->wdata); cm_ReleaseSCache(dscp); cm_ReleaseUser(userp); if ( WANTS_DFS_PATHNAMES(inp) || pnc ) @@ -7479,7 +7504,7 @@ long smb_ReceiveCoreCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) if (!smb_IsLegalFilename(lastNamep)) return CM_ERROR_BADNTFILENAME; - osi_Log1(smb_logp, "SMB receive create [%s]", osi_LogSaveString( smb_logp, pathp )); + osi_Log1(smb_logp, "SMB receive create [%S]", osi_LogSaveClientString( smb_logp, pathp )); #ifdef DEBUG_VERBOSE { char *hexp; @@ -8109,6 +8134,7 @@ void smb_Server(VOID *parmp) UCHAR rc; smb_vc_t *vcp = NULL; smb_t *smbp; + extern void rx_StartClientThread(void); rx_StartClientThread(); @@ -8438,7 +8464,7 @@ void smb_Listener(void *parmp) INT_PTR lana = (INT_PTR) parmp; char eventName[MAX_PATH]; - sprintf(eventName,"smb_Listener_lana_%d", (char)lana); + sprintf(eventName,"smb_Listener_lana_%d", (unsigned char)lana); ListenerShutdown[lana] = thrd_CreateEvent(NULL, FALSE, FALSE, eventName); if ( GetLastError() == ERROR_ALREADY_EXISTS ) thrd_ResetEvent(ListenerShutdown[lana]); @@ -8587,7 +8613,7 @@ void smb_Listener(void *parmp) } lock_ObtainMutex(&vcp->mx); - strcpy(vcp->rname, rname); + cm_Utf8ToUtf16(rname, -1, vcp->rname, lengthof(vcp->rname)); vcp->flags |= flags; lock_ReleaseMutex(&vcp->mx); @@ -8867,6 +8893,8 @@ int smb_NetbiosInit(int locked) strcpy(smb_localNamep, cm_NetbiosName); afsi_log("smb_localNamep is >%s<", smb_localNamep); + /* Also copy the value to the client character encoded string */ + cm_Utf8ToClientString(cm_NetbiosName, -1, cm_NetbiosNameC, MAX_NB_NAME_LENGTH); if (smb_LANadapter == LANA_INVALID) { ncbp->ncb_command = NCBENUM; @@ -9455,10 +9483,10 @@ void smb_Init(osi_log_t *logp, int useV3, * It is actually the domain for local logins, and we are acting as * a local SMB server. */ - bufsize = sizeof(smb_ServerDomainName) - 1; - GetComputerName(smb_ServerDomainName, &bufsize); + bufsize = lengthof(smb_ServerDomainName) - 1; + GetComputerNameW(smb_ServerDomainName, &bufsize); smb_ServerDomainNameLength = bufsize + 1; /* bufsize doesn't include terminator */ - afsi_log("Setting SMB server domain name to [%s]", smb_ServerDomainName); + afsi_log("Setting SMB server domain name to [%S]", smb_ServerDomainName); } /* Start listeners, waiters, servers, and daemons */ @@ -9615,6 +9643,7 @@ void smb_Shutdown(void) char *smb_GetSharename() { char *name; + int len; /* Make sure we have been properly initialized. */ if (smb_localNamep == NULL) @@ -9623,10 +9652,11 @@ char *smb_GetSharename() /* Allocate space for \\\, plus the * terminator. */ - name = malloc(strlen(smb_localNamep) + strlen("ALL") + 4); - sprintf(name, "\\\\%s\\%s", smb_localNamep, "ALL"); + len = (strlen(smb_localNamep) + strlen("ALL") + 4) * sizeof(char); + name = malloc(len); + snprintf(name, len, "\\\\%s\\%s", smb_localNamep, "ALL"); return name; -} +} #ifdef LOG_PACKET @@ -9722,8 +9752,8 @@ int smb_DumpVCP(FILE *outputFile, char *cookie, int lock) { sprintf(output, "%s -- smb_fidp=0x%p, refCount=%d, fid=%d, vcp=0x%p, scp=0x%p, ioctlp=0x%p, NTopen_pathp=%s, NTopen_wholepathp=%s\r\n", cookie, fidp, fidp->refCount, fidp->fid, fidp->vcp, fidp->scp, fidp->ioctlp, - fidp->NTopen_pathp ? fidp->NTopen_pathp : "NULL", - fidp->NTopen_wholepathp ? fidp->NTopen_wholepathp : "NULL"); + fidp->NTopen_pathp ? fidp->NTopen_pathp : _C("NULL"), + fidp->NTopen_wholepathp ? fidp->NTopen_wholepathp : _C("NULL")); WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL); } @@ -9752,8 +9782,8 @@ int smb_DumpVCP(FILE *outputFile, char *cookie, int lock) { sprintf(output, "%s -- smb_fidp=0x%p, refCount=%d, fid=%d, vcp=0x%p, scp=0x%p, ioctlp=0x%p, NTopen_pathp=%s, NTopen_wholepathp=%s\r\n", cookie, fidp, fidp->refCount, fidp->fid, fidp->vcp, fidp->scp, fidp->ioctlp, - fidp->NTopen_pathp ? fidp->NTopen_pathp : "NULL", - fidp->NTopen_wholepathp ? fidp->NTopen_wholepathp : "NULL"); + fidp->NTopen_pathp ? fidp->NTopen_pathp : _C("NULL"), + fidp->NTopen_wholepathp ? fidp->NTopen_wholepathp : _C("NULL")); WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL); } diff --git a/src/WINNT/afsd/smb.h b/src/WINNT/afsd/smb.h index abb6f69..df1a64f 100644 --- a/src/WINNT/afsd/smb.h +++ b/src/WINNT/afsd/smb.h @@ -16,6 +16,8 @@ #endif #include +#include + /* Support largefiles by default */ #define AFS_LARGEFILES @@ -47,7 +49,7 @@ typedef struct smb { #define SMB_FLAGS_CANONICAL_PATHNAMES 0x10 #define SMB_FLAGS_REQUEST_OPLOCK 0x20 #define SMB_FLAGS_REQUEST_BATCH_OPLOCK 0x40 -#define SMB_FLAGS_SERVER_TO_CLIENT 0x80 +#define SMB_FLAGS_SERVER_TO_CLIENT 0x80 /* flg2 values */ @@ -226,7 +228,7 @@ typedef struct smb_vc { struct smb_user *usersp; /* the first child in the user session list */ struct smb_fid *fidsp; /* the first child in the open file list */ unsigned char errorCount; - char rname[17]; + clientchar_t rname[17]; int lana; char encKey[MSV1_0_CHALLENGE_LENGTH]; /* MSV1_0_CHALLENGE_LENGTH is 8 */ void * secCtx; /* security context when negotiating SMB extended auth @@ -268,8 +270,8 @@ typedef struct smb_username { long flags; /* flags; locked by mx */ osi_mutex_t mx; struct cm_user *userp; /* CM user structure */ - char *name; /* user name */ - char *machine; /* machine name */ + clientchar_t *name; /* user name */ + clientchar_t *machine; /* machine name */ time_t last_logoff_t; /* most recent logoff time */ } smb_username_t; @@ -302,7 +304,7 @@ typedef struct smb_tid { struct smb_vc *vcp; /* back ptr */ struct cm_user *userp; /* user logged in at the * tree connect level (base) */ - char *pathname; /* pathname derived from sharename */ + clientchar_t *pathname; /* pathname derived from sharename */ afs_uint32 deleteOk; /* ok to del: locked by smb_rctLock */ } smb_tid_t; @@ -343,8 +345,8 @@ typedef struct smb_fid { * the file on close, or to do a * change notification */ struct cm_scache *NTopen_dscp; /* parent directory (NT) */ - char *NTopen_pathp; /* path used in open (NT) */ - char *NTopen_wholepathp; /* entire path, not just last name */ + clientchar_t *NTopen_pathp; /* path used in open (NT) */ + clientchar_t *NTopen_wholepathp; /* entire path, not just last name */ int curr_chunk; /* chunk being read */ int prev_chunk; /* previous chunk read */ int raw_writers; /* pending async raw writes */ @@ -425,9 +427,9 @@ typedef struct smb_dirSearch { * locked by smb_globalLock */ unsigned short attribute; /* search attribute * (used for extended protocol) */ - char tidPath[256]; /* tid path */ - char relPath[1024]; /* relative path */ - char mask[256]; /* search mask for V3 */ + clientchar_t tidPath[256]; /* tid path */ + clientchar_t relPath[1024]; /* relative path */ + clientchar_t mask[256]; /* search mask for V3 */ } smb_dirSearch_t; #define SMB_DIRSEARCH_DELETE 1 /* delete struct when ref count zero */ @@ -438,7 +440,7 @@ typedef struct smb_dirSearch { /* type for patching directory listings */ typedef struct smb_dirListPatch { osi_queue_t q; - char *dptr; /* ptr to attr, time, data, sizel, sizeh */ + char *dptr; /* ptr to attr, time, data, sizel, sizeh */ long flags; /* flags. See below */ cm_fid_t fid; cm_dirEntry_t *dep; /* temp */ @@ -532,11 +534,11 @@ extern void smb_ReleaseTID(smb_tid_t *tidp, afs_uint32 locked); extern smb_user_t *smb_FindUID(smb_vc_t *vcp, unsigned short uid, int flags); -extern smb_username_t *smb_FindUserByName(char *usern, char *machine, afs_uint32 flags); +extern smb_username_t *smb_FindUserByName(clientchar_t *usern, clientchar_t *machine, afs_uint32 flags); -extern cm_user_t *smb_FindCMUserByName(char *usern, char *machine, afs_uint32 flags); +extern cm_user_t *smb_FindCMUserByName(clientchar_t *usern, clientchar_t *machine, afs_uint32 flags); -extern smb_user_t *smb_FindUserByNameThisSession(smb_vc_t *vcp, char *usern); +extern smb_user_t *smb_FindUserByNameThisSession(smb_vc_t *vcp, clientchar_t *usern); extern void smb_ReleaseUsername(smb_username_t *unp); @@ -548,7 +550,7 @@ extern cm_user_t *smb_GetUserFromVCP(smb_vc_t *vcp, smb_packet_t *inp); extern cm_user_t *smb_GetUserFromUID(smb_user_t *uidp); -extern long smb_LookupTIDPath(smb_vc_t *vcp, unsigned short tid, char ** tidPathp); +extern long smb_LookupTIDPath(smb_vc_t *vcp, unsigned short tid, clientchar_t ** tidPathp); extern smb_fid_t *smb_FindFID(smb_vc_t *vcp, unsigned short fid, int flags); @@ -561,9 +563,9 @@ extern void smb_ReleaseFID(smb_fid_t *fidp); extern long smb_CloseFID(smb_vc_t *vcp, smb_fid_t *fidp, cm_user_t *userp, afs_uint32 dosTime); -extern int smb_FindShare(smb_vc_t *vcp, smb_user_t *uidp, char *shareName, char **pathNamep); +extern int smb_FindShare(smb_vc_t *vcp, smb_user_t *uidp, clientchar_t *shareName, clientchar_t **pathNamep); -extern int smb_FindShareCSCPolicy(char *shareName); +extern int smb_FindShareCSCPolicy(clientchar_t *shareName); extern smb_dirSearch_t *smb_FindDirSearchNL(long cookie); @@ -599,36 +601,36 @@ extern void smb_SetSMBParmDouble(smb_packet_t *smbp, int slot, char *parmValuep) extern void smb_SetSMBParmByte(smb_packet_t *smbp, int slot, unsigned int parmValue); -extern void smb_StripLastComponent(char *outPathp, char **lastComponentp, - char *inPathp); +extern void smb_StripLastComponent(clientchar_t *outPathp, clientchar_t **lastComponentp, + clientchar_t *inPathp); #define SMB_STRF_FORCEASCII (1<<0) #define SMB_STRF_ANSIPATH (1<<1) #define SMB_STRF_IGNORENULL (1<<2) -extern unsigned char *smb_ParseASCIIBlock(smb_packet_t * pktp, unsigned char *inp, - char **chainpp, int flags); +extern clientchar_t *smb_ParseASCIIBlock(smb_packet_t * pktp, unsigned char *inp, + char **chainpp, int flags); -extern unsigned char *smb_ParseString(smb_packet_t * pktp, unsigned char * inp, - char ** chainpp, int flags); +extern clientchar_t *smb_ParseString(smb_packet_t * pktp, unsigned char * inp, + char ** chainpp, int flags); -extern unsigned char *smb_ParseStringBuf(const unsigned char * bufbase, - cm_space_t ** stringspp, - unsigned char *inp, size_t *pcb_max, - char **chainpp, int flags); +extern clientchar_t *smb_ParseStringBuf(const unsigned char * bufbase, + cm_space_t ** stringspp, + unsigned char *inp, size_t *pcb_max, + char **chainpp, int flags); -extern unsigned char *smb_ParseStringCb(smb_packet_t * pktp, unsigned char * inp, - size_t cb, char ** chainpp, int flags); +extern clientchar_t *smb_ParseStringCb(smb_packet_t * pktp, unsigned char * inp, + size_t cb, char ** chainpp, int flags); -extern unsigned char *smb_ParseStringCch(smb_packet_t * pktp, unsigned char * inp, - size_t cch, char ** chainpp, int flags); +extern clientchar_t *smb_ParseStringCch(smb_packet_t * pktp, unsigned char * inp, + size_t cch, char ** chainpp, int flags); extern unsigned char * smb_UnparseString(smb_packet_t * pktp, unsigned char * outp, - unsigned char * str, - size_t * plen, int flags); + clientchar_t * str, + size_t * plen, int flags); extern unsigned char *smb_ParseVblBlock(unsigned char *inp, char **chainpp, - int *lengthp); + int *lengthp); extern smb_packet_t *smb_GetResponsePacket(smb_vc_t *vcp, smb_packet_t *inp); @@ -660,7 +662,7 @@ extern int smb_maxMpxRequests; /* max # of mpx requests */ extern int smb_StoreAnsiFilenames; extern int smb_hideDotFiles; -extern unsigned int smb_IsDotFile(char *lastComp); +extern unsigned int smb_IsDotFile(clientchar_t *lastComp); extern afs_uint32 smb_AsyncStore; extern afs_uint32 smb_AsyncStoreSize; @@ -673,11 +675,11 @@ extern int smb_authType; /* Type of SMB authentication to be used. One from belo extern HANDLE smb_lsaHandle; /* LSA handle obtained during smb_init if using SMB auth */ extern ULONG smb_lsaSecPackage; /* LSA security package id. Set during smb_init */ -extern char smb_ServerDomainName[]; +extern clientchar_t smb_ServerDomainName[]; extern int smb_ServerDomainNameLength; -extern char smb_ServerOS[]; +extern clientchar_t smb_ServerOS[]; extern int smb_ServerOSLength; -extern char smb_ServerLanManager[]; +extern clientchar_t smb_ServerLanManager[]; extern int smb_ServerLanManagerLength; extern GUID smb_ServerGUID; extern LSA_STRING smb_lsaLogonOrigin; @@ -694,9 +696,9 @@ typedef struct _MSV1_0_LM20_CHALLENGE_RESPONSE { } MSV1_0_LM20_CHALLENGE_RESPONSE, *PMSV1_0_LM20_CHALLENGE_RESPONSE; /**/ -extern long smb_AuthenticateUserLM(smb_vc_t *vcp, char * accountName, char * primaryDomain, char * ciPwd, unsigned ciPwdLength, char * csPwd, unsigned csPwdLength); +extern long smb_AuthenticateUserLM(smb_vc_t *vcp, clientchar_t * accountName, clientchar_t * primaryDomain, char * ciPwd, unsigned ciPwdLength, char * csPwd, unsigned csPwdLength); -extern long smb_GetNormalizedUsername(char * usern, const char * accountName, const char * domainName); +extern long smb_GetNormalizedUsername(clientchar_t * usern, const clientchar_t * accountName, const clientchar_t * domainName); extern void smb_FormatResponsePacket(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *op); @@ -723,11 +725,11 @@ long smb_WriteData(smb_fid_t *fidp, osi_hyper_t *offsetp, afs_uint32 count, char extern long smb_ReadData(smb_fid_t *fidp, osi_hyper_t *offsetp, afs_uint32 count, char *op, cm_user_t *userp, long *readp); -extern long smb_Rename(smb_vc_t *vcp, smb_packet_t *inp, char *oldPathp, char *newPathp, int attrs); +extern long smb_Rename(smb_vc_t *vcp, smb_packet_t *inp, clientchar_t *oldPathp, clientchar_t *newPathp, int attrs); -extern long smb_Link(smb_vc_t *vcp, smb_packet_t *inp, char *oldPathp, char *newPathp); +extern long smb_Link(smb_vc_t *vcp, smb_packet_t *inp, clientchar_t *oldPathp, clientchar_t *newPathp); -extern BOOL smb_IsLegalFilename(char *filename); +extern BOOL smb_IsLegalFilename(clientchar_t *filename); extern char *smb_GetSharename(void); @@ -753,7 +755,11 @@ extern void smb_SetLanAdapterChangeDetected(void); #include "smb_ioctl.h" #include "smb_iocons.h" -cm_user_t *smb_FindOrCreateUser(smb_vc_t *vcp, char *usern); +cm_user_t *smb_FindOrCreateUser(smb_vc_t *vcp, clientchar_t *usern); + +int smb_DumpVCP(FILE *outputFile, char *cookie, int lock); + +void smb_Shutdown(void); #ifdef NOTSERVICE extern void smb_LogPacket(smb_packet_t *packet); diff --git a/src/WINNT/afsd/smb3.c b/src/WINNT/afsd/smb3.c index a1ed7f0..5c39322 100644 --- a/src/WINNT/afsd/smb3.c +++ b/src/WINNT/afsd/smb3.c @@ -43,7 +43,7 @@ smb_tran2Dispatch_t smb_rapDispatchTable[SMB_RAP_NOPCODES]; /* protected by the smb_globalLock */ smb_tran2Packet_t *smb_tran2AssemblyQueuep; -const char **smb_ExecutableExtensions = NULL; +const clientchar_t **smb_ExecutableExtensions = NULL; /* retrieve a held reference to a user structure corresponding to an incoming * request */ @@ -67,18 +67,18 @@ cm_user_t *smb_GetTran2User(smb_vc_t *vcp, smb_tran2Packet_t *inp) * Return boolean specifying if the path name is thought to be an * executable file. For now .exe or .dll. */ -afs_uint32 smb_IsExecutableFileName(const char *name) +afs_uint32 smb_IsExecutableFileName(const clientchar_t *name) { int i, j, len; if ( smb_ExecutableExtensions == NULL || name == NULL) return 0; - len = (int)strlen(name); + len = (int)cm_ClientStrLen(name); for ( i=0; smb_ExecutableExtensions[i]; i++) { - j = len - (int)strlen(smb_ExecutableExtensions[i]); - if (cm_stricmp_utf8N(smb_ExecutableExtensions[i], &name[j]) == 0) + j = len - (int)cm_ClientStrLen(smb_ExecutableExtensions[i]); + if (cm_ClientStrCmpI(smb_ExecutableExtensions[i], &name[j]) == 0) return 1; } @@ -124,9 +124,9 @@ unsigned long smb_ExtAttributes(cm_scache_t *scp) return attrs; } -int smb_V3IsStarMask(char *maskp) +int smb_V3IsStarMask(clientchar_t *maskp) { - char tc; + clientchar_t tc; while (tc = *maskp++) if (tc == '?' || tc == '*' || tc == '<' || tc == '>') @@ -134,20 +134,15 @@ int smb_V3IsStarMask(char *maskp) return 0; } -void OutputDebugF(char * format, ...) { +void OutputDebugF(clientchar_t * format, ...) { va_list args; - int len; - char * buffer; + clientchar_t vbuffer[1024]; va_start( args, format ); - len = _vscprintf( format, args ) // _vscprintf doesn't count - + 3; // terminating '\0' + '\n' - buffer = malloc( len * sizeof(char) ); - vsprintf( buffer, format, args ); - osi_Log0(smb_logp, osi_LogSaveString(smb_logp, buffer)); - strcat(buffer, "\n"); - OutputDebugString(buffer); - free( buffer ); + cm_ClientStrPrintfV(vbuffer, lengthof(vbuffer), format, args); + osi_Log1(smb_logp, "%S", osi_LogSaveClientString(smb_logp, vbuffer)); + cm_ClientStrCat(vbuffer, lengthof(vbuffer), _C("\n")); + OutputDebugStringW(vbuffer); } void OutputDebugHexDump(unsigned char * buffer, int len) { @@ -155,16 +150,16 @@ void OutputDebugHexDump(unsigned char * buffer, int len) { char buf[256]; static char tr[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; - OutputDebugF("Hexdump length [%d]",len); + OutputDebugF(_C("Hexdump length [%d]"),len); for (i=0;icreds; ctx = secCtx->ctx; @@ -334,7 +331,7 @@ long smb_AuthenticateUserExt(smb_vc_t * vcp, char * usern, char * secBlobIn, int &expiry); if (status != SEC_E_OK) { - OutputDebugF("Can't acquire Credentials handle [%lX]", status); + OutputDebugF(_C("Can't acquire Credentials handle [%lX]"), status); code = CM_ERROR_BADPASSWORD; /* means "try again when I'm sober" */ goto aue_0; } @@ -376,14 +373,14 @@ long smb_AuthenticateUserExt(smb_vc_t * vcp, char * usern, char * secBlobIn, int ); if (status == SEC_I_COMPLETE_NEEDED || status == SEC_I_COMPLETE_AND_CONTINUE) { - OutputDebugF("Completing token..."); + OutputDebugF(_C("Completing token...")); istatus = CompleteAuthToken(&ctx, &secBufOut); if ( istatus != SEC_E_OK ) - OutputDebugF("Token completion failed: %lX", istatus); + OutputDebugF(_C("Token completion failed: %lX"), istatus); } if (status == SEC_I_COMPLETE_AND_CONTINUE || status == SEC_I_CONTINUE_NEEDED) { - OutputDebugF("Continue needed"); + OutputDebugF(_C("Continue needed")); newSecCtx = malloc(sizeof(*newSecCtx)); @@ -403,16 +400,16 @@ long smb_AuthenticateUserExt(smb_vc_t * vcp, char * usern, char * secBlobIn, int if ((status == SEC_I_COMPLETE_NEEDED || status == SEC_E_OK || status == SEC_I_COMPLETE_AND_CONTINUE || status == SEC_I_CONTINUE_NEEDED) && secTokOut.pvBuffer) { - OutputDebugF("Need to send token back to client"); + OutputDebugF(_C("Need to send token back to client")); *secBlobOutLength = secTokOut.cbBuffer; *secBlobOut = malloc(secTokOut.cbBuffer); memcpy(*secBlobOut, secTokOut.pvBuffer, secTokOut.cbBuffer); - OutputDebugF("Outgoing token:"); + OutputDebugF(_C("Outgoing token:")); OutputDebugHexDump(*secBlobOut,*secBlobOutLength); } else if (status == SEC_E_INCOMPLETE_MESSAGE) { - OutputDebugF("Incomplete message"); + OutputDebugF(_C("Incomplete message")); newSecCtx = malloc(sizeof(*newSecCtx)); @@ -432,52 +429,52 @@ long smb_AuthenticateUserExt(smb_vc_t * vcp, char * usern, char * secBlobIn, int if (status == SEC_E_OK || status == SEC_I_COMPLETE_NEEDED) { /* woo hoo! */ - SecPkgContext_Names names; + SecPkgContext_NamesW names; - OutputDebugF("Authentication completed"); - OutputDebugF("Returned flags : [%lX]", flags); + OutputDebugF(_C("Authentication completed")); + OutputDebugF(_C("Returned flags : [%lX]"), flags); - if (!QueryContextAttributes(&ctx, SECPKG_ATTR_NAMES, &names)) { - OutputDebugF("Received name [%s]", names.sUserName); - strcpy(usern, names.sUserName); - strlwr(usern); /* in tandem with smb_GetNormalizedUsername */ + if (!QueryContextAttributesW(&ctx, SECPKG_ATTR_NAMES, &names)) { + OutputDebugF(_C("Received name [%s]"), names.sUserName); + cm_ClientStrCpy(usern, SMB_MAX_USERNAME_LENGTH, names.sUserName); + cm_ClientStrLwr(usern); /* in tandem with smb_GetNormalizedUsername */ FreeContextBuffer(names.sUserName); } else { /* Force the user to retry if the context is invalid */ - OutputDebugF("QueryContextAttributes Names failed [%x]", GetLastError()); + OutputDebugF(_C("QueryContextAttributes Names failed [%x]"), GetLastError()); code = CM_ERROR_BADPASSWORD; } } else if (!code) { switch ( status ) { case SEC_E_INVALID_TOKEN: - OutputDebugF("Returning bad password :: INVALID_TOKEN"); + OutputDebugF(_C("Returning bad password :: INVALID_TOKEN")); break; case SEC_E_INVALID_HANDLE: - OutputDebugF("Returning bad password :: INVALID_HANDLE"); + OutputDebugF(_C("Returning bad password :: INVALID_HANDLE")); break; case SEC_E_LOGON_DENIED: - OutputDebugF("Returning bad password :: LOGON_DENIED"); + OutputDebugF(_C("Returning bad password :: LOGON_DENIED")); break; case SEC_E_UNKNOWN_CREDENTIALS: - OutputDebugF("Returning bad password :: UNKNOWN_CREDENTIALS"); + OutputDebugF(_C("Returning bad password :: UNKNOWN_CREDENTIALS")); break; case SEC_E_NO_CREDENTIALS: - OutputDebugF("Returning bad password :: NO_CREDENTIALS"); + OutputDebugF(_C("Returning bad password :: NO_CREDENTIALS")); break; case SEC_E_CONTEXT_EXPIRED: - OutputDebugF("Returning bad password :: CONTEXT_EXPIRED"); + OutputDebugF(_C("Returning bad password :: CONTEXT_EXPIRED")); break; case SEC_E_INCOMPLETE_CREDENTIALS: - OutputDebugF("Returning bad password :: INCOMPLETE_CREDENTIALS"); + OutputDebugF(_C("Returning bad password :: INCOMPLETE_CREDENTIALS")); break; case SEC_E_WRONG_PRINCIPAL: - OutputDebugF("Returning bad password :: WRONG_PRINCIPAL"); + OutputDebugF(_C("Returning bad password :: WRONG_PRINCIPAL")); break; case SEC_E_TIME_SKEW: - OutputDebugF("Returning bad password :: TIME_SKEW"); + OutputDebugF(_C("Returning bad password :: TIME_SKEW")); break; default: - OutputDebugF("Returning bad password :: Status == %lX", status); + OutputDebugF(_C("Returning bad password :: Status == %lX"), status); } code = CM_ERROR_BADPASSWORD; } @@ -519,7 +516,7 @@ struct Lm20AuthBlob { TOKEN_SOURCE tsource; }; -long smb_AuthenticateUserLM(smb_vc_t *vcp, char * accountName, char * primaryDomain, char * ciPwd, unsigned ciPwdLength, char * csPwd, unsigned csPwdLength) +long smb_AuthenticateUserLM(smb_vc_t *vcp, clientchar_t * accountName, clientchar_t * primaryDomain, char * ciPwd, unsigned ciPwdLength, char * csPwd, unsigned csPwdLength) { NTSTATUS nts, ntsEx; struct Lm20AuthBlob lmAuth; @@ -530,11 +527,11 @@ long smb_AuthenticateUserLM(smb_vc_t *vcp, char * accountName, char * primaryDom LUID lmSession; HANDLE lmToken; - OutputDebugF("In smb_AuthenticateUser for user [%s] domain [%s]", accountName, primaryDomain); - OutputDebugF("ciPwdLength is %d and csPwdLength is %d", ciPwdLength, csPwdLength); + OutputDebugF(_C("In smb_AuthenticateUser for user [%s] domain [%s]"), accountName, primaryDomain); + OutputDebugF(_C("ciPwdLength is %d and csPwdLength is %d"), ciPwdLength, csPwdLength); if (ciPwdLength > P_RESP_LEN || csPwdLength > P_RESP_LEN) { - OutputDebugF("ciPwdLength or csPwdLength is too long"); + OutputDebugF(_C("ciPwdLength or csPwdLength is too long")); return CM_ERROR_BADPASSWORD; } @@ -543,12 +540,12 @@ long smb_AuthenticateUserLM(smb_vc_t *vcp, char * accountName, char * primaryDom lmAuth.lmlogon.MessageType = MsV1_0NetworkLogon; lmAuth.lmlogon.LogonDomainName.Buffer = lmAuth.primaryDomainW; - mbstowcs(lmAuth.primaryDomainW, primaryDomain, P_LEN); + cm_ClientStringToUtf16(primaryDomain, -1, lmAuth.primaryDomainW, P_LEN); lmAuth.lmlogon.LogonDomainName.Length = (USHORT)(wcslen(lmAuth.primaryDomainW) * sizeof(WCHAR)); lmAuth.lmlogon.LogonDomainName.MaximumLength = P_LEN * sizeof(WCHAR); lmAuth.lmlogon.UserName.Buffer = lmAuth.accountNameW; - mbstowcs(lmAuth.accountNameW, accountName, P_LEN); + cm_ClientStringToUtf16(accountName, -1, lmAuth.accountNameW, P_LEN); lmAuth.lmlogon.UserName.Length = (USHORT)(wcslen(lmAuth.accountNameW) * sizeof(WCHAR)); lmAuth.lmlogon.UserName.MaximumLength = P_LEN * sizeof(WCHAR); @@ -576,9 +573,14 @@ long smb_AuthenticateUserLM(smb_vc_t *vcp, char * accountName, char * primaryDom lmAuth.tgroups.Groups[0].Sid = NULL; lmAuth.tgroups.Groups[0].Attributes = 0; +#ifdef _WIN64 lmAuth.tsource.SourceIdentifier.HighPart = (DWORD)((LONG_PTR)vcp << 32); +#else + lmAuth.tsource.SourceIdentifier.HighPart = 0; +#endif lmAuth.tsource.SourceIdentifier.LowPart = (DWORD)((LONG_PTR)vcp & _UI32_MAX); - strcpy(lmAuth.tsource.SourceName,"OpenAFS"); /* 8 char limit */ + StringCchCopyA(lmAuth.tsource.SourceName, lengthof(lmAuth.tsource.SourceName), + "OpenAFS"); /* 8 char limit */ nts = LsaLogonUser( smb_lsaHandle, &smb_lsaLogonOrigin, @@ -599,8 +601,8 @@ long smb_AuthenticateUserLM(smb_vc_t *vcp, char * accountName, char * primaryDom osi_Log2(smb_logp,"LsaLogonUser failure: nts %u ntsEx %u", nts, ntsEx); - OutputDebugF("Return from LsaLogonUser is 0x%lX", nts); - OutputDebugF("Extended status is 0x%lX", ntsEx); + OutputDebugF(_C("Return from LsaLogonUser is 0x%lX"), nts); + OutputDebugF(_C("Extended status is 0x%lX"), ntsEx); if (nts == ERROR_SUCCESS) { /* free the token */ @@ -617,13 +619,13 @@ long smb_AuthenticateUserLM(smb_vc_t *vcp, char * accountName, char * primaryDom } /* The buffer pointed to by usern is assumed to be at least SMB_MAX_USERNAME_LENGTH bytes */ -long smb_GetNormalizedUsername(char * usern, const char * accountName, const char * domainName) +long smb_GetNormalizedUsername(clientchar_t * usern, const clientchar_t * accountName, const clientchar_t * domainName) { - char * atsign; - const char * domain; + clientchar_t * atsign; + const clientchar_t * domain; /* check if we have sane input */ - if ((strlen(accountName) + strlen(domainName) + 1) > SMB_MAX_USERNAME_LENGTH) + if ((cm_ClientStrLen(accountName) + cm_ClientStrLen(domainName) + 1) > SMB_MAX_USERNAME_LENGTH) return 1; /* we could get : [accountName][domainName] @@ -632,7 +634,7 @@ long smb_GetNormalizedUsername(char * usern, const char * accountName, const cha [user][]/[user][?] [][]/[][?] */ - atsign = strchr(accountName, '@'); + atsign = cm_ClientStrChr(accountName, '@'); if (atsign) /* [user@domain][] -> [user@domain][domain] */ domain = atsign + 1; @@ -645,18 +647,18 @@ long smb_GetNormalizedUsername(char * usern, const char * accountName, const cha /* Empty domains and empty usernames are usually sent from tokenless contexts. This way such logins will get an empty username (easy to check). I don't know when a non-empty username would be supplied with an anonymous domain, but *shrug* */ - strcpy(usern,accountName); + cm_ClientStrCpy(usern, SMB_MAX_USERNAME_LENGTH, accountName); else { /* TODO: what about WIN.MIT.EDU\user vs. WIN\user? */ - strcpy(usern,domain); - strcat(usern,"\\"); + cm_ClientStrCpy(usern, SMB_MAX_USERNAME_LENGTH, domain); + cm_ClientStrCat(usern, SMB_MAX_USERNAME_LENGTH, _C("\\")); if (atsign) - strncat(usern,accountName,atsign - accountName); + cm_ClientStrCat(usern, SMB_MAX_USERNAME_LENGTH, accountName); else - strcat(usern,accountName); - } + cm_ClientStrCat(usern, SMB_MAX_USERNAME_LENGTH, accountName); + } - strlwr(usern); + cm_ClientStrLwr(usern); return 0; } @@ -676,9 +678,9 @@ long smb_ReceiveV3SessionSetupX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t * unsigned short newUid; unsigned long caps = 0; smb_username_t *unp; - char *s1 = " "; + clientchar_t *s1 = _C(" "); long code = 0; - char usern[SMB_MAX_USERNAME_LENGTH]; + clientchar_t usern[SMB_MAX_USERNAME_LENGTH]; char *secBlobOut = NULL; int secBlobOutLength = 0; @@ -692,7 +694,7 @@ long smb_ReceiveV3SessionSetupX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t * char *secBlobIn; int secBlobInLength; - OutputDebugF("NT Session Setup: Extended"); + OutputDebugF(_C("NT Session Setup: Extended")); if (!(vcp->flags & SMB_VCFLAG_SESSX_RCVD)) { caps = smb_GetSMBParm(inp,10) | (((unsigned long) smb_GetSMBParm(inp,11)) << 16); @@ -727,14 +729,14 @@ long smb_ReceiveV3SessionSetupX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t * } else { unsigned ciPwdLength, csPwdLength; char *ciPwd, *csPwd; - char *accountName; - char *primaryDomain; + clientchar_t *accountName; + clientchar_t *primaryDomain; int datalen; if (smb_authType == SMB_AUTH_NTLM) - OutputDebugF("NT Session Setup: NTLM"); + OutputDebugF(_C("NT Session Setup: NTLM")); else - OutputDebugF("NT Session Setup: None"); + OutputDebugF(_C("NT Session Setup: None")); /* TODO: parse for extended auth as well */ ciPwdLength = smb_GetSMBParm(inp, 7); /* case insensitive password length */ @@ -742,7 +744,7 @@ long smb_ReceiveV3SessionSetupX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t * tp = smb_GetSMBData(inp, &datalen); - OutputDebugF("Session packet data size [%d]",datalen); + OutputDebugF(_C("Session packet data size [%d]"),datalen); ciPwd = tp; tp += ciPwdLength; @@ -752,10 +754,12 @@ long smb_ReceiveV3SessionSetupX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t * accountName = smb_ParseString(inp, tp, &tp, 0); primaryDomain = smb_ParseString(inp, tp, NULL, 0); - OutputDebugF("Account Name: %s",accountName); - OutputDebugF("Primary Domain: %s", primaryDomain); - OutputDebugF("Case Sensitive Password: %s", csPwd && csPwd[0] ? "yes" : "no"); - OutputDebugF("Case Insensitive Password: %s", ciPwd && ciPwd[0] ? "yes" : "no"); + OutputDebugF(_C("Account Name: %s"),accountName); + OutputDebugF(_C("Primary Domain: %s"), primaryDomain); + OutputDebugF(_C("Case Sensitive Password: %s"), + csPwd && csPwd[0] ? _C("yes") : _C("no")); + OutputDebugF(_C("Case Insensitive Password: %s"), + ciPwd && ciPwd[0] ? _C("yes") : _C("no")); if (smb_GetNormalizedUsername(usern, accountName, primaryDomain)) { /* shouldn't happen */ @@ -771,26 +775,26 @@ long smb_ReceiveV3SessionSetupX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t * if (smb_authType == SMB_AUTH_NTLM) { code = smb_AuthenticateUserLM(vcp, accountName, primaryDomain, ciPwd, ciPwdLength, csPwd, csPwdLength); if ( code ) - OutputDebugF("LM authentication failed [%d]", code); + OutputDebugF(_C("LM authentication failed [%d]"), code); else - OutputDebugF("LM authentication succeeded"); + OutputDebugF(_C("LM authentication succeeded")); } } } else { /* V3 */ unsigned ciPwdLength; char *ciPwd; - char *accountName; - char *primaryDomain; + clientchar_t *accountName; + clientchar_t *primaryDomain; switch ( smb_authType ) { case SMB_AUTH_EXTENDED: - OutputDebugF("V3 Session Setup: Extended"); + OutputDebugF(_C("V3 Session Setup: Extended")); break; case SMB_AUTH_NTLM: - OutputDebugF("V3 Session Setup: NTLM"); + OutputDebugF(_C("V3 Session Setup: NTLM")); break; default: - OutputDebugF("V3 Session Setup: None"); + OutputDebugF(_C("V3 Session Setup: None")); } ciPwdLength = smb_GetSMBParm(inp, 7); tp = smb_GetSMBData(inp, NULL); @@ -800,9 +804,9 @@ long smb_ReceiveV3SessionSetupX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t * accountName = smb_ParseString(inp, tp, &tp, 0); primaryDomain = smb_ParseString(inp, tp, NULL, 0); - OutputDebugF("Account Name: %s",accountName); - OutputDebugF("Primary Domain: %s", primaryDomain); - OutputDebugF("Case Insensitive Password: %s", ciPwd && ciPwd[0] ? "yes" : "no"); + OutputDebugF(_C("Account Name: %s"),accountName); + OutputDebugF(_C("Primary Domain: %s"), primaryDomain); + OutputDebugF(_C("Case Insensitive Password: %s"), ciPwd && ciPwd[0] ? _C("yes") : _C("no")); if ( smb_GetNormalizedUsername(usern, accountName, primaryDomain)) { /* shouldn't happen */ @@ -816,9 +820,9 @@ long smb_ReceiveV3SessionSetupX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t * if (smb_authType == SMB_AUTH_NTLM || smb_authType == SMB_AUTH_EXTENDED) { code = smb_AuthenticateUserLM(vcp,accountName,primaryDomain,ciPwd,ciPwdLength,"",0); if ( code ) - OutputDebugF("LM authentication failed [%d]", code); + OutputDebugF(_C("LM authentication failed [%d]"), code); else - OutputDebugF("LM authentication succeeded"); + OutputDebugF(_C("LM authentication succeeded")); } } @@ -848,7 +852,7 @@ long smb_ReceiveV3SessionSetupX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t * return code; } - OutputDebugF("Received username=[%s]", usern); + OutputDebugF(_C("Received username=[%s]"), usern); /* On Windows 2000, this function appears to be called more often than it is expected to be called. This resulted in multiple smb_user_t @@ -889,7 +893,7 @@ long smb_ReceiveV3SessionSetupX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t * lock_ObtainMutex(&vcp->mx); if (!vcp->uidCounter) vcp->uidCounter++; /* handle unlikely wraparounds */ - newUid = (strlen(usern)==0)?0:vcp->uidCounter++; + newUid = (cm_ClientStrLen(usern)==0)?0:vcp->uidCounter++; lock_ReleaseMutex(&vcp->mx); /* Create a new smb_user_t structure and connect them up */ @@ -912,8 +916,9 @@ long smb_ReceiveV3SessionSetupX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t * /* Also to the next chained message */ ((smb_t *)inp)->uid = newUid; - osi_Log3(smb_logp, "SMB3 session setup name %s creating ID %d%s", - osi_LogSaveString(smb_logp, usern), newUid, osi_LogSaveString(smb_logp, s1)); + osi_Log3(smb_logp, "SMB3 session setup name %S creating ID %d%S", + osi_LogSaveClientString(smb_logp, usern), newUid, + osi_LogSaveClientString(smb_logp, s1)); smb_SetSMBParm(outp, 2, 0); @@ -968,8 +973,8 @@ long smb_ReceiveV3UserLogoffX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *ou if (uidp) { smb_username_t * unp; - osi_Log2(smb_logp, "SMB3 user logoffX uid %d name %s", uidp->userID, - osi_LogSaveString(smb_logp, (uidp->unp) ? uidp->unp->name: " ")); + osi_Log2(smb_logp, "SMB3 user logoffX uid %d name %S", uidp->userID, + osi_LogSaveClientString(smb_logp, (uidp->unp) ? uidp->unp->name: _C(" "))); lock_ObtainMutex(&uidp->mx); uidp->flags |= SMB_USERFLAG_DELETE; @@ -1012,13 +1017,14 @@ long smb_ReceiveV3TreeConnectX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *o smb_tid_t *tidp; smb_user_t *uidp = NULL; unsigned short newTid; - char shareName[AFSPATHMAX]; - char *sharePath; + clientchar_t shareName[AFSPATHMAX]; + clientchar_t *sharePath; int shareFound; char *tp; - char *pathp; - char *passwordp; - char *servicep; + clientchar_t *slashp; + clientchar_t *pathp; + clientchar_t *passwordp; + clientchar_t *servicep; cm_user_t *userp = NULL; int ipc = 0; @@ -1030,18 +1036,19 @@ long smb_ReceiveV3TreeConnectX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *o pathp = smb_ParseString(inp, tp, &tp, SMB_STRF_ANSIPATH); servicep = smb_ParseString(inp, tp, &tp, SMB_STRF_FORCEASCII); - tp = strrchr(pathp, '\\'); - if (!tp) { + slashp = cm_ClientStrRChr(pathp, '\\'); + if (!slashp) { return CM_ERROR_BADSMB; } - strcpy(shareName, tp+1); + cm_ClientStrCpy(shareName, lengthof(shareName), slashp+1); - osi_Log3(smb_logp, "Tree connect pathp[%s] shareName[%s] service[%s]", - osi_LogSaveString(smb_logp, pathp), - osi_LogSaveString(smb_logp, shareName), - osi_LogSaveString(smb_logp, servicep)); + osi_Log3(smb_logp, "Tree connect pathp[%S] shareName[%S] service[%S]", + osi_LogSaveClientString(smb_logp, pathp), + osi_LogSaveClientString(smb_logp, shareName), + osi_LogSaveClientString(smb_logp, servicep)); - if (strcmp(servicep, "IPC") == 0 || strcmp(shareName, "IPC$") == 0) { + if (cm_ClientStrCmp(servicep, _C("IPC")) == 0 || + cm_ClientStrCmp(shareName, _C("IPC$")) == 0) { #ifndef NO_IPC osi_Log0(smb_logp, "TreeConnectX connecting to IPC$"); ipc = 1; @@ -1061,8 +1068,8 @@ long smb_ReceiveV3TreeConnectX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *o tidp = smb_FindTID(vcp, newTid, SMB_FLAG_CREATE); if (!ipc) { - if (!strcmp(shareName, "*.")) - strcpy(shareName, "all"); + if (!cm_ClientStrCmp(shareName, _C("*."))) + cm_ClientStrCpy(shareName, lengthof(shareName), _C("all")); shareFound = smb_FindShare(vcp, uidp, shareName, &sharePath); if (!shareFound) { if (uidp) @@ -1089,7 +1096,7 @@ long smb_ReceiveV3TreeConnectX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *o } smb_SetSMBParm(outp, 2, SMB_SUPPORT_SEARCH_BITS | (dwAdvertiseDFS ? SMB_SHARE_IS_IN_DFS : 0) | - (policy << 2)); + (policy << 2)); } } else { smb_SetSMBParm(outp, 2, 0); @@ -1112,13 +1119,13 @@ long smb_ReceiveV3TreeConnectX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *o if (!ipc) { size_t cb_data = 0; - tp = smb_UnparseString(outp, tp, "A:", &cb_data, SMB_STRF_FORCEASCII); - tp = smb_UnparseString(outp, tp, "AFS", &cb_data, 0); + tp = smb_UnparseString(outp, tp, _C("A:"), &cb_data, SMB_STRF_FORCEASCII); + tp = smb_UnparseString(outp, tp, _C("AFS"), &cb_data, 0); smb_SetSMBDataLength(outp, cb_data); } else { size_t cb_data = 0; - tp = smb_UnparseString(outp, tp, "IPC", &cb_data, SMB_STRF_FORCEASCII); + tp = smb_UnparseString(outp, tp, _C("IPC"), &cb_data, SMB_STRF_FORCEASCII); smb_SetSMBDataLength(outp, cb_data); } @@ -1141,7 +1148,7 @@ smb_tran2Packet_t *smb_FindTran2Packet(smb_vc_t *vcp, smb_packet_t *inp) } smb_tran2Packet_t *smb_NewTran2Packet(smb_vc_t *vcp, smb_packet_t *inp, - int totalParms, int totalData) + int totalParms, int totalData) { smb_tran2Packet_t *tp; smb_t *smbp; @@ -1179,14 +1186,14 @@ smb_tran2Packet_t *smb_NewTran2Packet(smb_vc_t *vcp, smb_packet_t *inp, } smb_tran2Packet_t *smb_GetTran2ResponsePacket(smb_vc_t *vcp, - smb_tran2Packet_t *inp, smb_packet_t *outp, - int totalParms, int totalData) + smb_tran2Packet_t *inp, smb_packet_t *outp, + int totalParms, int totalData) { smb_tran2Packet_t *tp; unsigned short parmOffset; unsigned short dataOffset; unsigned short dataAlign; - + tp = malloc(sizeof(*tp)); memset(tp, 0, sizeof(*tp)); smb_HoldVC(vcp); @@ -1244,8 +1251,8 @@ void smb_FreeTran2Packet(smb_tran2Packet_t *t2p) free(t2p); } -unsigned char *smb_ParseStringT2Parm(smb_tran2Packet_t * p, unsigned char * inp, - char ** chainpp, int flags) +clientchar_t *smb_ParseStringT2Parm(smb_tran2Packet_t * p, unsigned char * inp, + char ** chainpp, int flags) { size_t cb; @@ -1254,9 +1261,9 @@ unsigned char *smb_ParseStringT2Parm(smb_tran2Packet_t * p, unsigned char * inp, flags |= SMB_STRF_FORCEASCII; #endif - cb = p->totalParms - (inp - (unsigned char *)p->parmsp); - if (inp < (unsigned char *) p->parmsp || - inp > ((unsigned char *) p->parmsp) + p->totalParms) { + cb = p->totalParms - (inp - (char *)p->parmsp); + if (inp < (char *) p->parmsp || + inp >= ((char *) p->parmsp) + p->totalParms) { #ifdef DEBUG_UNICODE DebugBreak(); #endif @@ -1271,7 +1278,7 @@ unsigned char *smb_ParseStringT2Parm(smb_tran2Packet_t * p, unsigned char * inp, * sends an error response. */ void smb_SendTran2Error(smb_vc_t *vcp, smb_tran2Packet_t *t2p, - smb_packet_t *tp, long code) + smb_packet_t *tp, long code) { smb_t *smbp; unsigned short errCode; @@ -1533,16 +1540,13 @@ typedef struct smb_rap_share_list { int smb_rapCollectSharesProc(cm_scache_t *dscp, cm_dirEntry_t *dep, void *vrockp, osi_hyper_t *offp) { smb_rap_share_list_t * sp; - char name[MAX_PATH]; - - cm_NormalizeUtf8String(dep->name, -1, name, sizeof(name)/sizeof(char)); - if (name[0] == '.' && (!name[1] || (name[1] == '.' && !name[2]))) + if (dep->name[0] == '.' && (!dep->name[1] || (dep->name[1] == '.' && !dep->name[2]))) return 0; /* skip over '.' and '..' */ sp = (smb_rap_share_list_t *) vrockp; - strncpy(sp->shares[sp->cShare].shi0_netname, name, 12); + strncpy(sp->shares[sp->cShare].shi0_netname, dep->name, 12); sp->shares[sp->cShare].shi0_netname[12] = 0; sp->cShare++; @@ -1574,7 +1578,7 @@ long smb_ReceiveRAPNetShareEnum(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_ smb_rap_share_info_1_t * shares; USHORT cshare = 0; char * cstrp; - char thisShare[AFSPATHMAX]; + clientchar_t thisShare[AFSPATHMAX]; int i,j; DWORD dw; int nonrootShares; @@ -1586,13 +1590,13 @@ long smb_ReceiveRAPNetShareEnum(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_ tp = p->parmsp + 1; /* skip over function number (always 0) */ { - char * cdescp; + clientchar_t * cdescp; cdescp = smb_ParseStringT2Parm(p, (char *) tp, (char **) &tp, SMB_STRF_FORCEASCII); - if (strcmp(cdescp, "WrLeh")) + if (cm_ClientStrCmp(cdescp, _C("WrLeh"))) return CM_ERROR_INVAL; cdescp = smb_ParseStringT2Parm(p, (char *) tp, (char **) &tp, SMB_STRF_FORCEASCII); - if (strcmp(cdescp, "B13BWz")) + if (cm_ClientStrCmp(cdescp, _C("B13BWz"))) return CM_ERROR_INVAL; } @@ -1679,7 +1683,8 @@ long smb_ReceiveRAPNetShareEnum(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_ memset(outp->datap, 0, (sizeof(smb_rap_share_info_1_t) + REMARK_LEN) * nSharesRet); if (allSubmount) { - strcpy( shares[cshare].shi1_netname, "all" ); + StringCchCopyA(shares[cshare].shi1_netname, + lengthof(shares[cshare].shi1_netname), "all" ); shares[cshare].shi1_remark = (DWORD)(cstrp - outp->datap); /* type and pad are zero already */ cshare++; @@ -1689,11 +1694,12 @@ long smb_ReceiveRAPNetShareEnum(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_ if (hkSubmount) { for (dw=0; dw < nRegShares && cshare < nSharesRet; dw++) { len = sizeof(thisShare); - rv = RegEnumValue(hkSubmount, dw, thisShare, &len, NULL, NULL, NULL, NULL); + rv = RegEnumValueW(hkSubmount, dw, thisShare, &len, NULL, NULL, NULL, NULL); if (rv == ERROR_SUCCESS && - strlen(thisShare) && (!allSubmount || cm_stricmp_utf8N(thisShare,"all"))) { - strncpy(shares[cshare].shi1_netname, thisShare, - sizeof(shares->shi1_netname)-1); + cm_ClientStrLen(thisShare) && + (!allSubmount || cm_ClientStrCmpI(thisShare,_C("all")))) { + cm_ClientStringToUtf8(thisShare, -1, shares[cshare].shi1_netname, + lengthof( shares[cshare].shi1_netname )); shares[cshare].shi1_netname[sizeof(shares->shi1_netname)-1] = 0; /* unfortunate truncation */ shares[cshare].shi1_remark = (DWORD)(cstrp - outp->datap); cshare++; @@ -1709,7 +1715,8 @@ long smb_ReceiveRAPNetShareEnum(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_ nonrootShares = cshare; for (i=0; i < rootShares.cShare && cshare < nSharesRet; i++) { - /* in case there are collisions with submounts, submounts have higher priority */ + /* in case there are collisions with submounts, submounts have + higher priority */ for (j=0; j < nonrootShares; j++) if (!cm_stricmp_utf8(shares[j].shi1_netname, rootShares.shares[i].shi0_netname)) break; @@ -1719,7 +1726,8 @@ long smb_ReceiveRAPNetShareEnum(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_ continue; } - strcpy(shares[cshare].shi1_netname, rootShares.shares[i].shi0_netname); + StringCchCopyA(shares[cshare].shi1_netname, lengthof(shares[cshare].shi1_netname), + rootShares.shares[i].shi0_netname); shares[cshare].shi1_remark = (DWORD)(cstrp - outp->datap); cshare++; cstrp+=REMARK_LEN; @@ -1746,7 +1754,7 @@ long smb_ReceiveRAPNetShareGetInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_pack { smb_tran2Packet_t *outp; unsigned short * tp; - char * shareName; + clientchar_t * shareName; BOOL shareFound = FALSE; unsigned short infoLevel; unsigned short bufsize; @@ -1767,17 +1775,17 @@ long smb_ReceiveRAPNetShareGetInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_pack tp = p->parmsp + 1; /* skip over function number (always 1) */ { - char * cdescp; + clientchar_t * cdescp; cdescp = smb_ParseStringT2Parm(p, (char *) tp, (char **) &tp, SMB_STRF_FORCEASCII); - if (strcmp(cdescp, "zWrLh")) + if (cm_ClientStrCmp(cdescp, _C("zWrLh"))) return CM_ERROR_INVAL; cdescp = smb_ParseStringT2Parm(p, (char *) tp, (char **) &tp, SMB_STRF_FORCEASCII); - if (strcmp(cdescp, "B13") && - strcmp(cdescp, "B13BWz") && - strcmp(cdescp, "B13BWzWWWzB9B")) + if (cm_ClientStrCmp(cdescp, _C("B13")) && + cm_ClientStrCmp(cdescp, _C("B13BWz")) && + cm_ClientStrCmp(cdescp, _C("B13BWzWWWzB9B"))) return CM_ERROR_INVAL; } @@ -1797,7 +1805,7 @@ long smb_ReceiveRAPNetShareGetInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_pack else return CM_ERROR_INVAL; - if(!cm_stricmp_utf8N(shareName,"all") || !strcmp(shareName,"*.")) { + if(!cm_ClientStrCmpI(shareName, _C("all")) || !cm_ClientStrCmp(shareName,_C("*."))) { rv = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY, 0, KEY_QUERY_VALUE, &hkParam); if (rv == ERROR_SUCCESS) { @@ -1829,7 +1837,7 @@ long smb_ReceiveRAPNetShareGetInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_pack rv = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY "\\Submounts", 0, KEY_QUERY_VALUE, &hkSubmount); if (rv == ERROR_SUCCESS) { - rv = RegQueryValueEx(hkSubmount, shareName, NULL, NULL, NULL, NULL); + rv = RegQueryValueExW(hkSubmount, shareName, NULL, NULL, NULL, NULL); if (rv == ERROR_SUCCESS) { shareFound = TRUE; } @@ -1850,18 +1858,17 @@ long smb_ReceiveRAPNetShareGetInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_pack if (infoLevel == 0) { smb_rap_share_info_0_t * info = (smb_rap_share_info_0_t *) outp->datap; - strncpy(info->shi0_netname, shareName, sizeof(info->shi0_netname)-1); - info->shi0_netname[sizeof(info->shi0_netname)-1] = 0; + cm_ClientStringToUtf8(shareName, -1, info->shi0_netname, + lengthof(info->shi0_netname)); } else if(infoLevel == SMB_INFO_STANDARD) { smb_rap_share_info_1_t * info = (smb_rap_share_info_1_t *) outp->datap; - strncpy(info->shi1_netname, shareName, sizeof(info->shi1_netname)-1); + cm_ClientStringToUtf8(shareName, -1, info->shi1_netname, lengthof(info->shi1_netname)); info->shi1_netname[sizeof(info->shi1_netname)-1] = 0; info->shi1_remark = (DWORD)(((unsigned char *) (info + 1)) - outp->datap); /* type and pad are already zero */ } else { /* infoLevel==2 */ smb_rap_share_info_2_t * info = (smb_rap_share_info_2_t *) outp->datap; - strncpy(info->shi2_netname, shareName, sizeof(info->shi2_netname)-1); - info->shi2_netname[sizeof(info->shi2_netname)-1] = 0; + cm_ClientStringToUtf8(shareName, -1, info->shi2_netname, lengthof(info->shi2_netname)); info->shi2_remark = (DWORD)(((unsigned char *) (info + 1)) - outp->datap); info->shi2_permissions = ACCESS_ALL; info->shi2_max_uses = (unsigned short) -1; @@ -1907,15 +1914,16 @@ long smb_ReceiveRAPNetWkstaGetInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_pack tp = p->parmsp + 1; /* Skip over function number */ { - char * cdescp; + clientchar_t * cdescp; cdescp = smb_ParseStringT2Parm(p, (unsigned char*) tp, (char **) &tp, SMB_STRF_FORCEASCII); - if (strcmp(cdescp, "WrLh")) + if (cm_ClientStrCmp(cdescp, _C("WrLh"))) return CM_ERROR_INVAL; + cdescp = smb_ParseStringT2Parm(p, (unsigned char*) tp, (char **) &tp, SMB_STRF_FORCEASCII); - if (strcmp(cdescp, "zzzBBzz")) + if (cm_ClientStrCmp(cdescp, _C("zzzBBzz"))) return CM_ERROR_INVAL; } @@ -1945,7 +1953,7 @@ long smb_ReceiveRAPNetWkstaGetInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_pack cstrp = (char *) (info + 1); info->wki10_computername = (DWORD) (cstrp - outp->datap); - strcpy(cstrp, smb_localNamep); + StringCbCopyA(cstrp, totalData, smb_localNamep); cstrp += strlen(cstrp) + 1; info->wki10_username = (DWORD) (cstrp - outp->datap); @@ -1953,14 +1961,15 @@ long smb_ReceiveRAPNetWkstaGetInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_pack if (uidp) { lock_ObtainMutex(&uidp->mx); if(uidp->unp && uidp->unp->name) - strcpy(cstrp, uidp->unp->name); + cm_ClientStringToUtf8(uidp->unp->name, -1, + cstrp, totalData/sizeof(char) - (cstrp - outp->datap)); lock_ReleaseMutex(&uidp->mx); smb_ReleaseUID(uidp); } cstrp += strlen(cstrp) + 1; info->wki10_langroup = (DWORD) (cstrp - outp->datap); - strcpy(cstrp, "WORKGROUP"); + StringCbCopyA(cstrp, totalData - (cstrp - outp->datap)*sizeof(char), "WORKGROUP"); cstrp += strlen(cstrp) + 1; /* TODO: Not sure what values these should take, but these work */ @@ -1968,7 +1977,8 @@ long smb_ReceiveRAPNetWkstaGetInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_pack info->wki10_ver_minor = 1; info->wki10_logon_domain = (DWORD) (cstrp - outp->datap); - strcpy(cstrp, smb_ServerDomainName); + cm_ClientStringToUtf8(smb_ServerDomainName, -1, + cstrp, totalData/sizeof(char) - (cstrp - outp->datap)); cstrp += strlen(cstrp) + 1; info->wki10_oth_domains = (DWORD) (cstrp - outp->datap); @@ -2023,16 +2033,16 @@ long smb_ReceiveRAPNetServerGetInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_pac tp = p->parmsp + 1; /* Skip over function number */ { - char * cdescp; + clientchar_t * cdescp; - cdescp = smb_ParseStringT2Parm(p, (unsigned char*) tp, (char **) &tp, + cdescp = smb_ParseStringT2Parm(p, (unsigned char *) tp, (char **) &tp, SMB_STRF_FORCEASCII); - if (strcmp(cdescp, "WrLh")) + if (cm_ClientStrCmp(cdescp, _C("WrLh"))) return CM_ERROR_INVAL; cdescp = smb_ParseStringT2Parm(p, (unsigned char*) tp, (char **) &tp, SMB_STRF_FORCEASCII); - if (strcmp(cdescp, "B16") || - strcmp(cdescp, "B16BBDz")) + if (cm_ClientStrCmp(cdescp, _C("B16")) || + cm_ClientStrCmp(cdescp, _C("B16BBDz"))) return CM_ERROR_INVAL; } @@ -2057,11 +2067,11 @@ long smb_ReceiveRAPNetServerGetInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_pac if (infoLevel == 0) { info0 = (smb_rap_server_info_0_t *) outp->datap; cstrp = (char *) (info0 + 1); - strcpy(info0->sv0_name, "AFS"); + StringCchCopyA(info0->sv0_name, lengthof(info0->sv0_name), "AFS"); } else { /* infoLevel == SMB_INFO_STANDARD */ info1 = (smb_rap_server_info_1_t *) outp->datap; cstrp = (char *) (info1 + 1); - strcpy(info1->sv1_name, "AFS"); + StringCchCopyA(info1->sv1_name, lengthof(info1->sv1_name), "AFS"); info1->sv1_type = SMB_SV_TYPE_SERVER | @@ -2072,9 +2082,9 @@ long smb_ReceiveRAPNetServerGetInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_pac info1->sv1_version_minor = 1; info1->sv1_comment_or_master_browser = (DWORD) (cstrp - outp->datap); - strcpy(cstrp, smb_ServerComment); + StringCbCopyA(cstrp, smb_ServerCommentLen, smb_ServerComment); - cstrp += smb_ServerCommentLen; + cstrp += smb_ServerCommentLen / sizeof(char); } totalData = (DWORD)(cstrp - outp->datap); @@ -2211,7 +2221,7 @@ long smb_ReceiveV3Tran2A(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) /* TRANS2_OPEN2 */ long smb_ReceiveTran2Open(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op) { - char *pathp; + clientchar_t *pathp; smb_tran2Packet_t *outp; long code = 0; cm_space_t *spacep; @@ -2223,7 +2233,7 @@ long smb_ReceiveTran2Open(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op) int initialModeBits; smb_fid_t *fidp; int attributes; - char *lastNamep; + clientchar_t *lastNamep; afs_uint32 dosTime; int openFun; int trunc; @@ -2232,7 +2242,7 @@ long smb_ReceiveTran2Open(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op) int openAction; int parmSlot; /* which parm we're dealing with */ long returnEALength; - char *tidPathp; + clientchar_t *tidPathp; cm_req_t req; int created = 0; @@ -2263,13 +2273,13 @@ long smb_ReceiveTran2Open(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op) outp = smb_GetTran2ResponsePacket(vcp, p, op, 40, 0); spacep = cm_GetSpace(); - smb_StripLastComponent(spacep->data, &lastNamep, pathp); + smb_StripLastComponent(spacep->wdata, &lastNamep, pathp); if (lastNamep && - (cm_stricmp_utf8N(lastNamep, SMB_IOCTL_FILENAME) == 0 || - cm_stricmp_utf8N(lastNamep, "\\srvsvc") == 0 || - cm_stricmp_utf8N(lastNamep, "\\wkssvc") == 0 || - cm_stricmp_utf8N(lastNamep, "\\ipc$") == 0)) { + (cm_ClientStrCmpI(lastNamep, _C(SMB_IOCTL_FILENAME)) == 0 || + cm_ClientStrCmpI(lastNamep, _C("\\srvsvc")) == 0 || + cm_ClientStrCmpI(lastNamep, _C("\\wkssvc")) == 0 || + cm_ClientStrCmpI(lastNamep, _C("\\ipc$")) == 0)) { /* special case magic file name for receiving IOCTL requests * (since IOCTL calls themselves aren't getting through). */ @@ -2350,7 +2360,7 @@ long smb_ReceiveTran2Open(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op) CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, userp, tidPathp, &req, &scp); if (code != 0) { - code = cm_NameI(cm_data.rootSCachep, spacep->data, + code = cm_NameI(cm_data.rootSCachep, spacep->wdata, CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, userp, tidPathp, &req, &dscp); cm_FreeSpace(spacep); @@ -2363,7 +2373,8 @@ long smb_ReceiveTran2Open(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op) #ifdef DFS_SUPPORT if (dscp->fileType == CM_SCACHETYPE_DFSLINK) { - int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp, spacep->data); + int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp, + (clientchar_t*) spacep->data); cm_ReleaseSCache(dscp); cm_ReleaseUser(userp); smb_FreeTran2Packet(outp); @@ -2634,7 +2645,7 @@ long smb_ReceiveTran2QFSInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t * /* we're supposed to pad it out with zeroes to the end */ memset(&qi.u.volumeInfo.label, 0, sizeof(qi.u.volumeInfo.label)); - smb_UnparseString(op, qi.u.volumeInfo.label, "AFS", &sz, 0); + smb_UnparseString(op, qi.u.volumeInfo.label, _C("AFS"), &sz, 0); responseSize = sizeof(unsigned long) + sizeof(char) + max(12, sz); break; @@ -2696,7 +2707,7 @@ long smb_ReceiveTran2QFSInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t * #ifdef SMB_UNICODE } #endif - smb_UnparseString(op, qi.u.FSattributeInfo.FSname, "AFS", &sz, 0); + smb_UnparseString(op, qi.u.FSattributeInfo.FSname, _C("AFS"), &sz, 0); qi.u.FSattributeInfo.FSnameLength = sz; responseSize = @@ -2734,9 +2745,9 @@ long smb_ReceiveTran2SetFSInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t } struct smb_ShortNameRock { - char *maskp; + clientchar_t *maskp; unsigned int vnode; - char *shortName; + clientchar_t *shortName; size_t shortNameLen; }; @@ -2744,17 +2755,17 @@ int cm_GetShortNameProc(cm_scache_t *scp, cm_dirEntry_t *dep, void *vrockp, osi_hyper_t *offp) { struct smb_ShortNameRock *rockp; - char normName[MAX_PATH]; - char *shortNameEnd; + normchar_t normName[MAX_PATH]; + clientchar_t *shortNameEnd; rockp = vrockp; - cm_NormalizeUtf8String(dep->name, -1, normName, sizeof(normName)/sizeof(char)); + cm_FsStringToNormString(dep->name, -1, normName, sizeof(normName)/sizeof(clientchar_t)); /* compare both names and vnodes, though probably just comparing vnodes * would be safe enough. */ - if (cm_stricmp_utf8(normName, rockp->maskp) != 0) + if (cm_NormStrCmpI(normName, rockp->maskp) != 0) return 0; if (ntohl(dep->fid.vnode) != rockp->vnode) return 0; @@ -2764,13 +2775,13 @@ int cm_GetShortNameProc(cm_scache_t *scp, cm_dirEntry_t *dep, void *vrockp, rockp->shortNameLen = shortNameEnd - rockp->shortName; return CM_ERROR_STOPNOW; -} +} -long cm_GetShortName(char *pathp, cm_user_t *userp, cm_req_t *reqp, - char *tidPathp, int vnode, char *shortName, size_t *shortNameLenp) +long cm_GetShortName(clientchar_t *pathp, cm_user_t *userp, cm_req_t *reqp, + clientchar_t *tidPathp, int vnode, clientchar_t *shortName, size_t *shortNameLenp) { struct smb_ShortNameRock rock; - char *lastNamep; + clientchar_t *lastNamep; cm_space_t *spacep; cm_scache_t *dscp; int caseFold = CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD; @@ -2778,10 +2789,11 @@ long cm_GetShortName(char *pathp, cm_user_t *userp, cm_req_t *reqp, osi_hyper_t thyper; spacep = cm_GetSpace(); - smb_StripLastComponent(spacep->data, &lastNamep, pathp); + smb_StripLastComponent(spacep->wdata, &lastNamep, pathp); - code = cm_NameI(cm_data.rootSCachep, spacep->data, caseFold, userp, tidPathp, - reqp, &dscp); + code = cm_NameI(cm_data.rootSCachep, spacep->wdata, + caseFold, userp, tidPathp, + reqp, &dscp); cm_FreeSpace(spacep); if (code) return code; @@ -2828,7 +2840,7 @@ long smb_ReceiveTran2QPathInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t int responseSize; unsigned short attributes; unsigned long extAttributes; - char shortName[13]; + clientchar_t shortName[13]; size_t len; cm_user_t *userp; cm_space_t *spacep; @@ -2836,9 +2848,9 @@ long smb_ReceiveTran2QPathInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t int scp_mx_held = 0; int delonclose = 0; long code = 0; - char *pathp; - char *tidPathp; - char *lastComp; + clientchar_t *pathp; + clientchar_t *tidPathp; + clientchar_t *lastComp; cm_req_t req; cm_InitReq(&req); @@ -2870,8 +2882,8 @@ long smb_ReceiveTran2QPathInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t } pathp = smb_ParseStringT2Parm(p, (char *) (&p->parmsp[3]), NULL, SMB_STRF_ANSIPATH); - osi_Log2(smb_logp, "T2 QPathInfo type 0x%x path %s", infoLevel, - osi_LogSaveString(smb_logp, pathp)); + osi_Log2(smb_logp, "T2 QPathInfo type 0x%x path %S", infoLevel, + osi_LogSaveClientString(smb_logp, pathp)); outp = smb_GetTran2ResponsePacket(vcp, p, opx, 2, responseSize); @@ -2922,12 +2934,12 @@ long smb_ReceiveTran2QPathInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t */ if (infoLevel == SMB_QUERY_FILE_BASIC_INFO) { spacep = cm_GetSpace(); - smb_StripLastComponent(spacep->data, &lastComp, pathp); + smb_StripLastComponent(spacep->wdata, &lastComp, pathp); #ifndef SPECIAL_FOLDERS /* Make sure that lastComp is not NULL */ if (lastComp) { - if (cm_stricmp_utf8N(lastComp, "\\desktop.ini") == 0) { - code = cm_NameI(cm_data.rootSCachep, spacep->data, + if (cm_ClientStrCmpIA(lastComp, _C("\\desktop.ini")) == 0) { + code = cm_NameI(cm_data.rootSCachep, spacep->wdata, CM_FLAG_CASEFOLD | CM_FLAG_DIRSEARCH | CM_FLAG_FOLLOW, @@ -2935,7 +2947,8 @@ long smb_ReceiveTran2QPathInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t if (code == 0) { #ifdef DFS_SUPPORT if (dscp->fileType == CM_SCACHETYPE_DFSLINK) { - int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp, spacep->data); + int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp, + spacep->wdata); if ( WANTS_DFS_PATHNAMES(p) || pnc ) code = CM_ERROR_PATH_NOT_COVERED; else @@ -3134,15 +3147,15 @@ long smb_ReceiveTran2SetPathInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet long code = 0; smb_fid_t *fidp; unsigned short infoLevel; - char * pathp; + clientchar_t * pathp; smb_tran2Packet_t *outp; smb_tran2QPathInfo_t *spi; cm_user_t *userp; cm_scache_t *scp, *dscp; cm_req_t req; cm_space_t *spacep; - char *tidPathp; - char *lastComp; + clientchar_t *tidPathp; + clientchar_t *lastComp; cm_InitReq(&req); @@ -3160,8 +3173,8 @@ long smb_ReceiveTran2SetPathInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet pathp = smb_ParseStringT2Parm(p, (char *) (&p->parmsp[3]), NULL, SMB_STRF_ANSIPATH); - osi_Log2(smb_logp, "T2 SetPathInfo infolevel 0x%x path %s", infoLevel, - osi_LogSaveString(smb_logp, pathp)); + osi_Log2(smb_logp, "T2 SetPathInfo infolevel 0x%x path %S", infoLevel, + osi_LogSaveClientString(smb_logp, pathp)); userp = smb_GetTran2User(vcp, p); if (!userp) { @@ -3198,12 +3211,12 @@ long smb_ReceiveTran2SetPathInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet */ if (infoLevel == SMB_QUERY_FILE_BASIC_INFO) { spacep = cm_GetSpace(); - smb_StripLastComponent(spacep->data, &lastComp, pathp); + smb_StripLastComponent(spacep->wdata, &lastComp, pathp); #ifndef SPECIAL_FOLDERS /* Make sure that lastComp is not NULL */ if (lastComp) { - if (cm_stricmp_utf8N(lastComp, "\\desktop.ini") == 0) { - code = cm_NameI(cm_data.rootSCachep, spacep->data, + if (cm_ClientStrCmpI(lastComp, _C("\\desktop.ini")) == 0) { + code = cm_NameI(cm_data.rootSCachep, spacep->wdata, CM_FLAG_CASEFOLD | CM_FLAG_DIRSEARCH | CM_FLAG_FOLLOW, @@ -3211,7 +3224,8 @@ long smb_ReceiveTran2SetPathInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet if (code == 0) { #ifdef DFS_SUPPORT if (dscp->fileType == CM_SCACHETYPE_DFSLINK) { - int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp, spacep->data); + int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp, + spacep->wdata); if ( WANTS_DFS_PATHNAMES(p) || pnc ) code = CM_ERROR_PATH_NOT_COVERED; else @@ -3463,7 +3477,7 @@ long smb_ReceiveTran2QFileInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t } else if (infoLevel == SMB_QUERY_FILE_NAME_INFO) { size_t len = 0; - char *name; + clientchar_t *name; lock_ReleaseRead(&scp->rw); lock_ObtainMutex(&fidp->mx); @@ -3471,7 +3485,7 @@ long smb_ReceiveTran2QFileInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t if (fidp->NTopen_wholepathp) name = fidp->NTopen_wholepathp; else - name = "\\"; /* probably can't happen */ + name = _C("\\"); /* probably can't happen */ lock_ReleaseMutex(&fidp->mx); smb_UnparseString(opx, qfi.u.QFfileNameInfo.fileName, name, &len, 0); @@ -3763,8 +3777,8 @@ smb_ReceiveTran2GetDFSReferral(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t #ifdef DFS_SUPPORT long code = 0; int maxReferralLevel = 0; - char requestFileName[1024] = ""; - char referralPath[1024] = ""; + clientchar_t requestFileName[1024] = _C(""); + clientchar_t referralPath[1024] = _C(""); smb_tran2Packet_t *outp = 0; cm_user_t *userp = 0; cm_scache_t *scp = 0; @@ -3779,26 +3793,24 @@ smb_ReceiveTran2GetDFSReferral(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t maxReferralLevel = p->parmsp[0]; GetCPInfo(CP_ACP, &CodePageInfo); - WideCharToMultiByte(CP_ACP, 0, (LPCWSTR) &p->parmsp[1], -1, - requestFileName, 1024, NULL, NULL); + cm_Utf16ToClientString(&p->parmsp[1], -1, requestFileName, lengthof(requestFileName)); - osi_Log2(smb_logp,"ReceiveTran2GetDfsReferral [%d][%s]", - maxReferralLevel, osi_LogSaveString(smb_logp, requestFileName)); + osi_Log2(smb_logp,"ReceiveTran2GetDfsReferral [%d][%S]", + maxReferralLevel, osi_LogSaveClientString(smb_logp, requestFileName)); - nbnLen = (int)strlen(cm_NetbiosName); - reqLen = (int)strlen(requestFileName); + nbnLen = (int)cm_ClientStrLen(cm_NetbiosNameC); + reqLen = (int)cm_ClientStrLen(requestFileName); if (reqLen > nbnLen + 2 && requestFileName[0] == '\\' && - !_strnicmp(cm_NetbiosName,&requestFileName[1],nbnLen) && + !cm_ClientStrCmpNI(cm_NetbiosNameC, &requestFileName[1], nbnLen) && requestFileName[nbnLen+1] == '\\') { int found = 0; - if (!_strnicmp("all",&requestFileName[nbnLen+2],3) || - !_strnicmp("*.",&requestFileName[nbnLen+2],2)) - { + if (!cm_ClientStrCmpNI(_C("all"), &requestFileName[nbnLen+2], 3) || + !cm_ClientStrCmpNI(_C("*."), &requestFileName[nbnLen+2], 2)) { found = 1; - strcpy(referralPath, requestFileName); + cm_ClientStrCpy(referralPath, lengthof(referralPath), requestFileName); refLen = reqLen; } else { userp = smb_GetTran2User(vcp, p); @@ -3807,7 +3819,7 @@ smb_ReceiveTran2GetDFSReferral(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t code = CM_ERROR_BADSMB; goto done; } - + /* * We have a requested path. Check to see if it is something * we know about. @@ -3822,20 +3834,20 @@ smb_ReceiveTran2GetDFSReferral(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t if (code == 0) { /* Yes it is. */ found = 1; - strcpy(referralPath, requestFileName); + cm_ClientStrCpy(referralPath, lengthof(referralPath), requestFileName); refLen = reqLen; } else if (code == CM_ERROR_PATH_NOT_COVERED ) { - char temp[1024]; - char pathName[1024]; - char *lastComponent; + clientchar_t temp[1024]; + clientchar_t pathName[1024]; + clientchar_t *lastComponent; /* * we have a msdfs link somewhere in the path * we should figure out where in the path the link is. * and return it. */ - osi_Log1(smb_logp,"ReceiveTran2GetDfsReferral PATH_NOT_COVERED [%s]", requestFileName); + osi_Log1(smb_logp,"ReceiveTran2GetDfsReferral PATH_NOT_COVERED [%S]", requestFileName); - strcpy(temp, &requestFileName[nbnLen+2]); + cm_ClientStrCpy(temp, lengthof(temp), &requestFileName[nbnLen+2]); do { if (dscp) { @@ -3863,15 +3875,16 @@ smb_ReceiveTran2GetDFSReferral(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t /* scp should now be the DfsLink we are looking for */ if (scp) { /* figure out how much of the input path was used */ - reqLen = (int)(nbnLen+2 + strlen(pathName) + 1 + strlen(lastComponent)); + reqLen = (int)(nbnLen+2 + cm_ClientStrLen(pathName) + 1 + cm_ClientStrLen(lastComponent)); - strcpy(referralPath, &scp->mountPointStringp[strlen("msdfs:")]); - refLen = (int)strlen(referralPath); + cm_FsStringToClientString(&scp->mountPointStringp[strlen("msdfs:")], -1, + referralPath, lengthof(referralPath)); + refLen = (int)cm_ClientStrLen(referralPath); found = 1; } } else { - char shareName[MAX_PATH + 1]; - char *p, *q; + clientchar_t shareName[MAX_PATH + 1]; + clientchar_t *p, *q; /* we may have a sharename that is a volume reference */ for (p = &requestFileName[nbnLen+2], q = shareName; *p && *p != '\\'; p++, q++) @@ -3881,14 +3894,15 @@ smb_ReceiveTran2GetDFSReferral(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *q = '\0'; if (smb_FindShare(vcp, vcp->usersp, shareName, &p)) { - code = cm_NameI(cm_data.rootSCachep, "", + code = cm_NameI(cm_data.rootSCachep, _C(""), CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, userp, p, &req, &scp); free(p); if (code == 0) { found = 1; - strcpy(referralPath, requestFileName); + cm_ClientStrCpy(referralPath, lengthof(referralPath), + requestFileName); refLen = reqLen; } } @@ -3973,7 +3987,7 @@ smb_ReceiveTran2ReportDFSInconsistency(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_ static long smb_ApplyV3DirListPatches(cm_scache_t *dscp,smb_dirListPatch_t **dirPatchespp, - char * tidPathp, char * relPathp, + clientchar_t * tidPathp, clientchar_t * relPathp, int infoLevel, cm_user_t *userp, cm_req_t *reqp) { @@ -3988,7 +4002,7 @@ smb_ApplyV3DirListPatches(cm_scache_t *dscp,smb_dirListPatch_t **dirPatchespp, smb_dirListPatch_t *npatchp; afs_uint32 rights; afs_int32 mustFake = 0; - char path[AFSPATHMAX]; + clientchar_t path[AFSPATHMAX]; code = cm_FindACLCache(dscp, userp, &rights); if (code == 0 && !(rights & PRSFS_READ)) @@ -4008,7 +4022,8 @@ smb_ApplyV3DirListPatches(cm_scache_t *dscp,smb_dirListPatch_t **dirPatchespp, for(patchp = *dirPatchespp; patchp; patchp = (smb_dirListPatch_t *) osi_QNext(&patchp->q)) { - snprintf(path, AFSPATHMAX, "%s\\%s", relPathp ? relPathp : "", patchp->dep->name); + cm_ClientStrPrintfN(path, lengthof(path),_C("%s\\%S"), + relPathp ? relPathp : _C(""), patchp->dep->name); reqp->relPathp = path; reqp->tidPathp = tidPathp; @@ -4100,7 +4115,8 @@ smb_ApplyV3DirListPatches(cm_scache_t *dscp,smb_dirListPatch_t **dirPatchespp, code = 0; while (code == 0 && scp->fileType == CM_SCACHETYPE_SYMLINK) { lock_ReleaseWrite(&scp->rw); - snprintf(path, AFSPATHMAX, "%s\\%s", relPathp ? relPathp : "", patchp->dep->name); + cm_ClientStrPrintfN(path, lengthof(path), _C("%s\\%S"), + relPathp ? relPathp : _C(""), patchp->dep->name); reqp->relPathp = path; reqp->tidPathp = tidPathp; code = cm_EvaluateSymLink(dscp, scp, &targetScp, userp, reqp); @@ -4197,165 +4213,6 @@ smb_ApplyV3DirListPatches(cm_scache_t *dscp,smb_dirListPatch_t **dirPatchespp, return code; } -// char table for case insensitive comparison -char mapCaseTable[256]; - -VOID initUpperCaseTable(VOID) -{ - int i; - for (i = 0; i < 256; ++i) - mapCaseTable[i] = toupper(i); - // make '"' match '.' - mapCaseTable[(int)'"'] = toupper('.'); - // make '<' match '*' - mapCaseTable[(int)'<'] = toupper('*'); - // make '>' match '?' - mapCaseTable[(int)'>'] = toupper('?'); -} - -/*! \brief Compare 'pattern' (containing metacharacters '*' and '?') with the file name 'name'. - - \note This procedure works recursively calling itself. - - \param[in] pattern string containing metacharacters. - \param[in] name File name to be compared with 'pattern'. - - \return BOOL : TRUE/FALSE (match/mistmatch) -*/ -BOOL -szWildCardMatchFileName(char * pattern, char * name, int casefold) -{ - char upattern[MAX_PATH]; - char uname[MAX_PATH]; - - char * pename; // points to the last 'name' character - char * p; - char * pattern_next; - - if (casefold) { - StringCbCopyA(upattern, sizeof(upattern), pattern); - strupr_utf8(upattern, sizeof(upattern)); - pattern = upattern; - - StringCbCopyA(uname, sizeof(uname), name); - strupr_utf8(uname, sizeof(uname)); - name = uname; - - /* The following translations all work on single byte - characters */ - for (p=pattern; *p; p++) { - if (*p == '"') *p = '.'; continue; - if (*p == '<') *p = '*'; continue; - if (*p == '>') *p = '?'; continue; - } - - for (p=name; *p; p++) { - if (*p == '"') *p = '.'; continue; - if (*p == '<') *p = '*'; continue; - if (*p == '>') *p = '?'; continue; - } - } - - pename = char_prev_utf8(name + strlen(name)); - - while (*name) { - switch (*pattern) { - case '?': - pattern = char_next_utf8(pattern); - if (*name == '.') - continue; - name = char_next_utf8(name); - break; - - case '*': - pattern = char_next_utf8(pattern); - if (*pattern == '\0') - return TRUE; - - pattern_next = char_next_utf8(pattern); - - for (p = pename; p >= name; p = char_prev_utf8(p)) { - if (*p == *pattern && - szWildCardMatchFileName(pattern_next, - char_next_utf8(p), FALSE)) - return TRUE; - } /* endfor */ - return FALSE; - - default: - if (*name != *pattern) - return FALSE; - pattern = char_next_utf8(pattern); - name = char_next_utf8(name); - break; - } /* endswitch */ - } /* endwhile */ - - /* if all we have left are wildcards, then we match */ - for (;*pattern; pattern = char_next_utf8(pattern)) { - if (*pattern != '*' && *pattern != '?') - return FALSE; - } - return TRUE; -} - -/* do a case-folding search of the star name mask with the name in namep. - * Return 1 if we match, otherwise 0. - */ -int smb_V3MatchMask(char *namep, char *maskp, int flags) -{ - char * newmask; - int i, j, star, qmark, casefold, retval; - - /* make sure we only match 8.3 names, if requested */ - if ((flags & CM_FLAG_8DOT3) && !cm_Is8Dot3(namep)) - return 0; - - casefold = (flags & CM_FLAG_CASEFOLD) ? 1 : 0; - - /* optimize the pattern: - * if there is a mixture of '?' and '*', - * for example the sequence "*?*?*?*" - * must be turned into the form "*" - */ - newmask = (char *)malloc(strlen(maskp)+1); - for ( i=0, j=0, star=0, qmark=0; maskp[i]; i++) { - switch ( maskp[i] ) { - case '?': - case '>': - qmark++; - break; - case '<': - case '*': - star++; - break; - default: - if ( star ) { - newmask[j++] = '*'; - } else if ( qmark ) { - while ( qmark-- ) - newmask[j++] = '?'; - } - newmask[j++] = maskp[i]; - star = 0; - qmark = 0; - } - } - if ( star ) { - newmask[j++] = '*'; - } else if ( qmark ) { - while ( qmark-- ) - newmask[j++] = '?'; - } - newmask[j++] = '\0'; - - retval = szWildCardMatchFileName(newmask, namep, casefold) ? 1:0; - - free(newmask); - return retval; -} - - /* smb_ReceiveTran2SearchDir implements both * Tran2_Find_First and Tran2_Find_Next */ @@ -4381,7 +4238,7 @@ long smb_T2SearchDirSingle(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op int attribute; long nextCookie; long code = 0, code2 = 0; - char *pathp = 0; + clientchar_t *pathp = 0; int maxCount; smb_dirListPatch_t *dirListPatchesp; smb_dirListPatch_t *curPatchp; @@ -4397,16 +4254,16 @@ long smb_T2SearchDirSingle(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op unsigned long maxReturnData; /* max # of return data */ long maxReturnParms; /* max # of return parms */ long bytesInBuffer; /* # data bytes in the output buffer */ - char *maskp; /* mask part of path */ + clientchar_t *maskp; /* mask part of path */ int infoLevel; int searchFlags; int eos; smb_tran2Packet_t *outp; /* response packet */ - char *tidPathp = 0; + clientchar_t *tidPathp = 0; int align; - char shortName[13]; /* 8.3 name if needed */ + clientchar_t shortName[13]; /* 8.3 name if needed */ int NeedShortName; - char *shortNameEnd; + clientchar_t *shortNameEnd; cm_dirEntry_t * dep = NULL; cm_req_t req; char * s; @@ -4429,16 +4286,16 @@ long smb_T2SearchDirSingle(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op searchFlags = p->parmsp[2]; pathp = smb_ParseStringT2Parm(p, (char *) &(p->parmsp[6]), NULL, SMB_STRF_ANSIPATH); nextCookie = 0; - maskp = strrchr(pathp, '\\'); + maskp = cm_ClientStrRChr(pathp, '\\'); if (maskp == NULL) maskp = pathp; else maskp++; /* skip over backslash */ /* track if this is likely to match a lot of entries */ - osi_Log2(smb_logp, "smb_T2SearchDirSingle : path[%s], mask[%s]", - osi_LogSaveString(smb_logp, pathp), - osi_LogSaveString(smb_logp, maskp)); + osi_Log2(smb_logp, "smb_T2SearchDirSingle : path[%S], mask[%S]", + osi_LogSaveClientString(smb_logp, pathp), + osi_LogSaveClientString(smb_logp, maskp)); switch ( infoLevel ) { case SMB_INFO_STANDARD: @@ -4512,8 +4369,8 @@ long smb_T2SearchDirSingle(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op outp = smb_GetTran2ResponsePacket(vcp, p, opx, maxReturnParms, maxReturnData); - osi_Log2(smb_logp, "T2SDSingle search dir count %d [%s]", - maxCount, osi_LogSaveString(smb_logp, pathp)); + osi_Log2(smb_logp, "T2SDSingle search dir count %d [%S]", + maxCount, osi_LogSaveClientString(smb_logp, pathp)); /* bail out if request looks bad */ if (!pathp) { @@ -4530,7 +4387,7 @@ long smb_T2SearchDirSingle(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op /* try to get the vnode for the path name next */ spacep = cm_GetSpace(); - smb_StripLastComponent(spacep->data, NULL, pathp); + smb_StripLastComponent(spacep->wdata, NULL, pathp); code = smb_LookupTIDPath(vcp, p->tid, &tidPathp); if (code) { cm_ReleaseUser(userp); @@ -4539,7 +4396,7 @@ long smb_T2SearchDirSingle(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op return 0; } - code = cm_NameI(cm_data.rootSCachep, spacep->data, + code = cm_NameI(cm_data.rootSCachep, spacep->wdata, CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, userp, tidPathp, &req, &scp); cm_FreeSpace(spacep); @@ -4616,17 +4473,17 @@ long smb_T2SearchDirSingle(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op dfid.vnode = htonl(targetscp->fid.vnode); dfid.unique = htonl(targetscp->fid.unique); - cm_Gen8Dot3NameInt(maskp, &dfid, shortName, &shortNameEnd); + cm_Gen8Dot3NameIntW(maskp, &dfid, shortName, &shortNameEnd); NeedShortName = 1; } else { NeedShortName = 0; } - osi_Log4(smb_logp, "T2SDSingle dir vn %u uniq %u name %s (%s)", - htonl(targetscp->fid.vnode), - htonl(targetscp->fid.unique), - osi_LogSaveString(smb_logp, pathp), - NeedShortName ? osi_LogSaveString(smb_logp, shortName) : ""); + osi_Log4(smb_logp, "T2SDSingle dir vn %u uniq %u name %S (%S)", + htonl(targetscp->fid.vnode), + htonl(targetscp->fid.unique), + osi_LogSaveClientString(smb_logp, pathp), + (NeedShortName)? osi_LogSaveClientString(smb_logp, shortName) : _C("")); /* Eliminate entries that don't match requested attributes */ if (smb_hideDotFiles && !(attribute & SMB_ATTR_HIDDEN) && @@ -4709,10 +4566,9 @@ long smb_T2SearchDirSingle(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op #ifdef SMB_UNICODE int nchars; - nchars = MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS, - shortName, -1, - fp->u.FfileBothDirectoryInfo.shortName, - sizeof(fp->u.FfileBothDirectoryInfo.shortName) / sizeof(wchar_t)); + nchars = cm_ClientStringToUtf16(shortName, -1, + fp->u.FfileBothDirectoryInfo.shortName, + sizeof(fp->u.FfileBothDirectoryInfo.shortName)/sizeof(wchar_t)); if (nchars > 0) fp->u.FfileBothDirectoryInfo.shortNameLength = (nchars - 1)*sizeof(wchar_t); else @@ -4721,7 +4577,7 @@ long smb_T2SearchDirSingle(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op #else strcpy(fp->u.FfileBothDirectoryInfo.shortName, shortName); - fp->u.FfileBothDirectoryInfo.shortNameLength = strlen(shortName); + fp->u.FfileBothDirectoryInfo.shortNameLength = cm_ClientStrLen(shortName); #endif } /* Fallthrough */ @@ -4765,8 +4621,11 @@ long smb_T2SearchDirSingle(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op cm_SetFid(&curPatchp->fid, targetscp->fid.cell, targetscp->fid.volume, targetscp->fid.vnode, targetscp->fid.unique); /* temp */ - dep = (cm_dirEntry_t *)malloc(sizeof(cm_dirEntry_t)+strlen(maskp)); - strcpy(dep->name, maskp); + { + int namelen = cm_ClientStringToFsString(maskp, -1, NULL, 0); + dep = (cm_dirEntry_t *)malloc(sizeof(cm_dirEntry_t)+namelen); + cm_ClientStringToFsString(maskp, -1, dep->name, namelen); + } dep->fid.vnode = targetscp->fid.vnode; dep->fid.unique = targetscp->fid.unique; curPatchp->dep = dep; @@ -4788,7 +4647,7 @@ long smb_T2SearchDirSingle(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op } /* apply the patches */ - code2 = smb_ApplyV3DirListPatches(scp, &dirListPatchesp, tidPathp, spacep->data, infoLevel, userp, &req); + code2 = smb_ApplyV3DirListPatches(scp, &dirListPatchesp, tidPathp, spacep->wdata, infoLevel, userp, &req); outp->parmsp[0] = 0; outp->parmsp[1] = 1; /* number of names returned */ @@ -4830,7 +4689,7 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t long nextCookie; char *tp; long code = 0, code2 = 0; - char *pathp; + clientchar_t *pathp; cm_dirEntry_t *dep = 0; int maxCount; smb_dirListPatch_t *dirListPatchesp = 0; @@ -4861,17 +4720,17 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t unsigned long maxReturnParms; /* max # of return parms */ long bytesInBuffer; /* # data bytes in the output buffer */ int starPattern; - char *maskp; /* mask part of path */ + clientchar_t *maskp; /* mask part of path */ int infoLevel; int searchFlags; int eos; smb_tran2Packet_t *outp; /* response packet */ - char *tidPathp; + clientchar_t *tidPathp; unsigned int align; - char shortName[13]; /* 8.3 name if needed */ + clientchar_t shortName[13]; /* 8.3 name if needed */ int NeedShortName; int foundInexact; - char *shortNameEnd; + clientchar_t *shortNameEnd; int fileType; cm_fid_t fid; cm_req_t req; @@ -4890,7 +4749,7 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t searchFlags = p->parmsp[2]; pathp = smb_ParseStringT2Parm(p, (char *) (&p->parmsp[6]), NULL, SMB_STRF_ANSIPATH); nextCookie = 0; - maskp = strrchr(pathp, '\\'); + maskp = cm_ClientStrRChr(pathp, '\\'); if (maskp == NULL) maskp = pathp; else @@ -4921,7 +4780,7 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t dsp = smb_NewDirSearch(1); dsp->attribute = attribute; - strcpy(dsp->mask, maskp); /* and save mask */ + cm_ClientStrCpy(dsp->mask, lengthof(dsp->mask), maskp); /* and save mask */ } else { osi_assertx(p->opcode == 2, "invalid opcode"); @@ -5020,8 +4879,8 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t outp = smb_GetTran2ResponsePacket(vcp, p, opx, maxReturnParms, maxReturnData); - osi_Log2(smb_logp, "T2 receive search dir count %d [%s]", - maxCount, osi_LogSaveString(smb_logp, pathp)); + osi_Log2(smb_logp, "T2 receive search dir count %d [%S]", + maxCount, osi_LogSaveClientString(smb_logp, pathp)); /* bail out if request looks bad */ if (p->opcode == 1 && !pathp) { @@ -5050,7 +4909,7 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t code = 0; } else { spacep = cm_GetSpace(); - smb_StripLastComponent(spacep->data, NULL, pathp); + smb_StripLastComponent(spacep->wdata, NULL, pathp); code = smb_LookupTIDPath(vcp, p->tid, &tidPathp); if (code) { cm_ReleaseUser(userp); @@ -5062,10 +4921,10 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t return 0; } - strcpy(dsp->tidPath, tidPathp ? tidPathp : "/"); - strcpy(dsp->relPath, spacep->data); + cm_ClientStrCpy(dsp->tidPath, lengthof(dsp->tidPath), tidPathp ? tidPathp : _C("/")); + cm_ClientStrCpy(dsp->relPath, lengthof(dsp->relPath), spacep->wdata); - code = cm_NameI(cm_data.rootSCachep, spacep->data, + code = cm_NameI(cm_data.rootSCachep, spacep->wdata, CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, userp, tidPathp, &req, &scp); cm_FreeSpace(spacep); @@ -5144,7 +5003,8 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t returnedNames = 0; bytesInBuffer = 0; while (1) { - char normName[MAX_PATH]; /* Normalized name */ + normchar_t normName[MAX_PATH]; /* Normalized name */ + clientchar_t cfileName[MAX_PATH]; /* Non-normalized name */ op = origOp; if (searchFlags & TRAN2_FIND_FLAG_RETURN_RESUME_KEYS) @@ -5318,30 +5178,31 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t if (dep->fid.vnode == 0) goto nextEntry; /* This entry is not in use */ - cm_NormalizeUtf8String(dep->name, -1, normName, sizeof(normName)/sizeof(char)); + cm_FsStringToClientString(dep->name, -1, cfileName, lengthof(cfileName)); + cm_ClientStringToNormString(cfileName, -1, normName, lengthof(normName)); /* Need 8.3 name? */ NeedShortName = 0; if (infoLevel == SMB_FIND_FILE_BOTH_DIRECTORY_INFO && - !cm_Is8Dot3(dep->name)) { + !cm_Is8Dot3(cfileName)) { cm_Gen8Dot3Name(dep, shortName, &shortNameEnd); NeedShortName = 1; } - osi_Log4(smb_logp, "T2 search dir vn %u uniq %u name %s (%s)", - dep->fid.vnode, dep->fid.unique, - osi_LogSaveString(smb_logp, normName), - NeedShortName ? osi_LogSaveString(smb_logp, shortName) : ""); + osi_Log4(smb_logp, "T2 search dir vn %u uniq %u name %S (%S)", + dep->fid.vnode, dep->fid.unique, + osi_LogSaveClientString(smb_logp, cfileName), + NeedShortName ? osi_LogSaveClientString(smb_logp, shortName) : _C("")); /* When matching, we are using doing a case fold if we have a wildcard mask. * If we get a non-wildcard match, it's a lookup for a specific file. */ - if (smb_V3MatchMask(normName, maskp, (starPattern? CM_FLAG_CASEFOLD : 0)) || - (NeedShortName && smb_V3MatchMask(shortName, maskp, CM_FLAG_CASEFOLD))) + if (cm_MatchMask(normName, maskp, (starPattern? CM_FLAG_CASEFOLD : 0)) || + (NeedShortName && cm_MatchMask(shortName, maskp, CM_FLAG_CASEFOLD))) { /* Eliminate entries that don't match requested attributes */ if (smb_hideDotFiles && !(dsp->attribute & SMB_ATTR_HIDDEN) && - smb_IsDotFile(normName)) { + smb_IsDotFile(cfileName)) { osi_Log0(smb_logp, "T2 search dir skipping hidden"); goto nextEntry; /* no hidden files */ } @@ -5349,7 +5210,8 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t if (!(dsp->attribute & SMB_ATTR_DIRECTORY)) /* no directories */ { /* We have already done the cm_TryBulkStat above */ - cm_SetFid(&fid, scp->fid.cell, scp->fid.volume, ntohl(dep->fid.vnode), ntohl(dep->fid.unique)); + cm_SetFid(&fid, scp->fid.cell, scp->fid.volume, + ntohl(dep->fid.vnode), ntohl(dep->fid.unique)); fileType = cm_FindFileType(&fid); /* osi_Log2(smb_logp, "smb_ReceiveTran2SearchDir: file %s " * "has filetype %d", dep->name, fileType); @@ -5364,7 +5226,7 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t /* finally check if this name will fit */ onbytes = 0; - smb_UnparseString(opx, NULL, normName, &onbytes, SMB_STRF_ANSIPATH); + smb_UnparseString(opx, NULL, cfileName, &onbytes, SMB_STRF_ANSIPATH); orbytes = ohbytes + onbytes; /* now, we round up the record to a 4 byte alignment, @@ -5380,7 +5242,7 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t if (orbytes + bytesInBuffer + align > maxReturnData) { osi_Log1(smb_logp, "T2 dir search exceed max return data %d", - maxReturnData); + maxReturnData); break; } @@ -5392,7 +5254,7 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t memset(origOp, 0, orbytes); onbytes = 0; - smb_UnparseString(opx, origOp + ohbytes, normName, &onbytes, SMB_STRF_ANSIPATH); + smb_UnparseString(opx, origOp + ohbytes, cfileName, &onbytes, SMB_STRF_ANSIPATH); switch (infoLevel) { case SMB_INFO_STANDARD: @@ -5417,19 +5279,19 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t #ifdef SMB_UNICODE int nchars; - nchars = MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS, - shortName, -1, - fp->u.FfileBothDirectoryInfo.shortName, - sizeof(fp->u.FfileBothDirectoryInfo.shortName) / sizeof(wchar_t)); + nchars = cm_ClientStringToUtf16(shortName, -1, + fp->u.FfileBothDirectoryInfo.shortName, + sizeof(fp->u.FfileBothDirectoryInfo.shortName)/sizeof(wchar_t)); if (nchars > 0) fp->u.FfileBothDirectoryInfo.shortNameLength = (nchars - 1)*sizeof(wchar_t); else fp->u.FfileBothDirectoryInfo.shortNameLength = 0; fp->u.FfileBothDirectoryInfo.reserved = 0; #else - strcpy(fp->u.FfileBothDirectoryInfo.shortName, - shortName); - fp->u.FfileBothDirectoryInfo.shortNameLength = strlen(shortName); + cm_ClientStrCpy(fp->u.FfileBothDirectoryInfo.shortName, + lengthof(fp->u.FfileBothDirectoryInfo.shortName), + shortName); + fp->u.FfileBothDirectoryInfo.shortNameLength = cm_ClientStrLen(shortName); #endif } /* Fallthrough */ @@ -5479,7 +5341,7 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t osi_QAdd((osi_queue_t **) &dirListPatchesp, &curPatchp->q); curPatchp->dptr = attrp; - if (smb_hideDotFiles && smb_IsDotFile(normName)) { + if (smb_hideDotFiles && smb_IsDotFile(cfileName)) { curPatchp->flags = SMB_DIRLISTPATCH_DOTFILE; } else { curPatchp->flags = 0; @@ -5506,8 +5368,8 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t } } /* if we're including this name */ else if (!starPattern && - !foundInexact && - smb_V3MatchMask(normName, maskp, CM_FLAG_CASEFOLD)) { + !foundInexact && + cm_MatchMask(normName, maskp, CM_FLAG_CASEFOLD)) { /* We were looking for exact matches, but here's an inexact one*/ foundInexact = 1; } @@ -5637,7 +5499,7 @@ long smb_ReceiveV3FindNotifyClose(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t /* SMB_COM_OPEN_ANDX */ long smb_ReceiveV3OpenX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - char *pathp; + clientchar_t *pathp; long code = 0; cm_space_t *spacep; int excl; @@ -5648,7 +5510,7 @@ long smb_ReceiveV3OpenX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) int initialModeBits; smb_fid_t *fidp; int attributes; - char *lastNamep; + clientchar_t *lastNamep; unsigned long dosTime; int openFun; int trunc; @@ -5656,7 +5518,7 @@ long smb_ReceiveV3OpenX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) int extraInfo; int openAction; int parmSlot; /* which parm we're dealing with */ - char *tidPathp; + clientchar_t *tidPathp; cm_req_t req; int created = 0; @@ -5683,13 +5545,13 @@ long smb_ReceiveV3OpenX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) SMB_STRF_ANSIPATH); spacep = inp->spacep; - smb_StripLastComponent(spacep->data, &lastNamep, pathp); + smb_StripLastComponent(spacep->wdata, &lastNamep, pathp); if (lastNamep && - (cm_stricmp_utf8N(lastNamep, SMB_IOCTL_FILENAME) == 0 || - cm_stricmp_utf8N(lastNamep, "\\srvsvc") == 0 || - cm_stricmp_utf8N(lastNamep, "\\wkssvc") == 0 || - cm_stricmp_utf8N(lastNamep, "ipc$") == 0)) { + (cm_ClientStrCmpIA(lastNamep, _C(SMB_IOCTL_FILENAME)) == 0 || + cm_ClientStrCmpIA(lastNamep, _C("\\srvsvc")) == 0 || + cm_ClientStrCmpIA(lastNamep, _C("\\wkssvc")) == 0 || + cm_ClientStrCmpIA(lastNamep, _C("ipc$")) == 0)) { /* special case magic file name for receiving IOCTL requests * (since IOCTL calls themselves aren't getting through). */ @@ -5763,7 +5625,7 @@ long smb_ReceiveV3OpenX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) #endif /* DFS_SUPPORT */ if (code != 0) { - code = cm_NameI(cm_data.rootSCachep, spacep->data, + code = cm_NameI(cm_data.rootSCachep, spacep->wdata, CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, userp, tidPathp, &req, &dscp); if (code) { @@ -5773,7 +5635,8 @@ long smb_ReceiveV3OpenX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) #ifdef DFS_SUPPORT if (dscp->fileType == CM_SCACHETYPE_DFSLINK) { - int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp, spacep->data); + int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp, + spacep->wdata); cm_ReleaseSCache(dscp); cm_ReleaseUser(userp); if ( WANTS_DFS_PATHNAMES(inp) || pnc ) @@ -5839,8 +5702,8 @@ long smb_ReceiveV3OpenX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) } else { osi_assertx(dscp != NULL, "null cm_scache_t"); - osi_Log1(smb_logp, "smb_ReceiveV3OpenX creating file %s", - osi_LogSaveString(smb_logp, lastNamep)); + osi_Log1(smb_logp, "smb_ReceiveV3OpenX creating file %S", + osi_LogSaveClientString(smb_logp, lastNamep)); openAction = 2; /* created file */ setAttr.mask = CM_ATTRMASK_CLIENTMODTIME; smb_UnixTimeFromDosUTime(&setAttr.clientModTime, dosTime); @@ -6727,7 +6590,7 @@ long smb_ReceiveV3ReadX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) /* SMB_COM_NT_CREATE_ANDX */ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - char *pathp, *realPathp; + clientchar_t *pathp, *realPathp; long code = 0; cm_space_t *spacep; cm_user_t *userp; @@ -6735,8 +6598,8 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) cm_scache_t *scp; /* file to create or open */ cm_scache_t *targetScp; /* if scp is a symlink */ cm_attr_t setAttr; - char *lastNamep; - char *treeStartp; + clientchar_t *lastNamep; + clientchar_t *treeStartp; unsigned short nameLength; unsigned int flags; unsigned int requestOpLock; @@ -6760,7 +6623,7 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) long fidflags; FILETIME ft; LARGE_INTEGER sz; - char *tidPathp; + clientchar_t *tidPathp; BOOL foundscp; cm_req_t req; int created = 0; @@ -6825,22 +6688,22 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) NULL, SMB_STRF_ANSIPATH); /* Sometimes path is not null-terminated, so we make a copy. */ - realPathp = malloc(nameLength+1); - memcpy(realPathp, pathp, nameLength); - realPathp[nameLength] = 0; + realPathp = malloc(nameLength+sizeof(clientchar_t)); + memcpy(realPathp, pathp, nameLength+sizeof(clientchar_t)); + realPathp[nameLength/sizeof(clientchar_t)] = 0; spacep = inp->spacep; - smb_StripLastComponent(spacep->data, &lastNamep, realPathp); + smb_StripLastComponent(spacep->wdata, &lastNamep, realPathp); - osi_Log1(smb_logp,"NTCreateX for [%s]",osi_LogSaveString(smb_logp,realPathp)); + osi_Log1(smb_logp,"NTCreateX for [%S]",osi_LogSaveClientString(smb_logp,realPathp)); osi_Log4(smb_logp,"... da=[%x] ea=[%x] cd=[%x] co=[%x]", desiredAccess, extAttributes, createDisp, createOptions); - osi_Log3(smb_logp,"... share=[%x] flags=[%x] lastNamep=[%s]", shareAccess, flags, osi_LogSaveString(smb_logp,(lastNamep?lastNamep:"null"))); + osi_Log3(smb_logp,"... share=[%x] flags=[%x] lastNamep=[%S]", shareAccess, flags, osi_LogSaveClientString(smb_logp,(lastNamep?lastNamep:_C("null")))); if (lastNamep && - (cm_stricmp_utf8N(lastNamep, SMB_IOCTL_FILENAME) == 0 || - cm_stricmp_utf8N(lastNamep, "\\srvsvc") == 0 || - cm_stricmp_utf8N(lastNamep, "\\wkssvc") == 0 || - cm_stricmp_utf8N(lastNamep, "ipc$") == 0)) { + (cm_ClientStrCmpIA(lastNamep, _C(SMB_IOCTL_FILENAME)) == 0 || + cm_ClientStrCmpIA(lastNamep, _C("\\srvsvc")) == 0 || + cm_ClientStrCmpIA(lastNamep, _C("\\wkssvc")) == 0 || + cm_ClientStrCmpIA(lastNamep, _C("ipc$")) == 0)) { /* special case magic file name for receiving IOCTL requests * (since IOCTL calls themselves aren't getting through). */ @@ -6932,7 +6795,7 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) tidPathp = NULL; } - osi_Log1(smb_logp, "NTCreateX tidPathp=[%s]", (tidPathp==NULL)?"null": osi_LogSaveString(smb_logp,tidPathp)); + osi_Log1(smb_logp, "NTCreateX tidPathp=[%S]", (tidPathp==NULL)?_C("null"): osi_LogSaveClientString(smb_logp,tidPathp)); /* compute open mode */ fidflags = 0; @@ -6964,12 +6827,13 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) if ( createDisp == FILE_CREATE || createDisp == FILE_OVERWRITE || createDisp == FILE_OVERWRITE_IF) { - code = cm_NameI(baseDirp, spacep->data, CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, + code = cm_NameI(baseDirp, spacep->wdata, CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, userp, tidPathp, &req, &dscp); if (code == 0) { #ifdef DFS_SUPPORT if (dscp->fileType == CM_SCACHETYPE_DFSLINK) { - int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp, spacep->data); + int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp, + spacep->wdata); cm_ReleaseSCache(dscp); cm_ReleaseUser(userp); free(realPathp); @@ -7032,15 +6896,16 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) if (dscp == NULL) { do { - char *tp; + clientchar_t *tp; - code = cm_NameI(baseDirp, spacep->data, - CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, - userp, tidPathp, &req, &dscp); + code = cm_NameI(baseDirp, spacep->wdata, + CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, + userp, tidPathp, &req, &dscp); #ifdef DFS_SUPPORT if (code == 0 && dscp->fileType == CM_SCACHETYPE_DFSLINK) { - int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp, spacep->data); + int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp, + spacep->wdata); if (scp) cm_ReleaseSCache(scp); cm_ReleaseSCache(dscp); @@ -7055,13 +6920,13 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) } #endif /* DFS_SUPPORT */ - if (code && - (tp = strrchr(spacep->data,'\\')) && - (createDisp == FILE_CREATE) && - (realDirFlag == 1)) { + if (code && + (tp = cm_ClientStrRChr(spacep->wdata, '\\')) && + (createDisp == FILE_CREATE) && + (realDirFlag == 1)) { *tp++ = 0; treeCreate = TRUE; - treeStartp = realPathp + (tp - spacep->data); + treeStartp = realPathp + (tp - spacep->wdata); if (*tp && !smb_IsLegalFilename(tp)) { cm_ReleaseUser(userp); @@ -7226,8 +7091,8 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) return CM_ERROR_NOSUCHFILE; } else if (realDirFlag == 0 || realDirFlag == -1) { osi_assertx(dscp != NULL, "null cm_scache_t"); - osi_Log1(smb_logp, "smb_ReceiveNTCreateX creating file %s", - osi_LogSaveString(smb_logp, lastNamep)); + osi_Log1(smb_logp, "smb_ReceiveNTCreateX creating file %S", + osi_LogSaveClientString(smb_logp, lastNamep)); openAction = 2; /* created file */ setAttr.mask = CM_ATTRMASK_CLIENTMODTIME; setAttr.clientModTime = time(NULL); @@ -7274,8 +7139,8 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) } /* lookup succeeded */ } } else { - char *tp, *pp; - char *cp; /* This component */ + clientchar_t *tp, *pp; + clientchar_t *cp; /* This component */ int clen = 0; /* length of component */ cm_scache_t *tscp1, *tscp2; int isLast = 0; @@ -7284,8 +7149,8 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) if ( !treeCreate ) treeStartp = lastNamep; osi_assertx(dscp != NULL, "null cm_scache_t"); - osi_Log1(smb_logp, "smb_ReceiveNTCreateX creating directory [%s]", - osi_LogSaveString(smb_logp, treeStartp)); + osi_Log1(smb_logp, "smb_ReceiveNTCreateX creating directory [%S]", + osi_LogSaveClientString(smb_logp, treeStartp)); openAction = 2; /* created directory */ /* if the request is to create the root directory @@ -7299,20 +7164,21 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) setAttr.clientModTime = time(NULL); pp = treeStartp; - cp = spacep->data; + cp = spacep->wdata; tscp1 = dscp; cm_HoldSCache(tscp1); tscp2 = NULL; while (pp && *pp) { - tp = strchr(pp, '\\'); + tp = cm_ClientStrChr(pp, '\\'); if (!tp) { - strcpy(cp,pp); - clen = (int)strlen(cp); + cm_ClientStrCpy(cp, lengthof(spacep->wdata) - (cp - spacep->wdata), pp); + clen = (int)cm_ClientStrLen(cp); isLast = 1; /* indicate last component. the supplied path never ends in a slash */ } else { clen = (int)(tp - pp); - strncpy(cp,pp,clen); + cm_ClientStrCpyN(cp, lengthof(spacep->wdata) - (cp - spacep->wdata), + pp, clen); *(cp + clen) = 0; tp++; } @@ -7325,10 +7191,10 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) code = cm_MakeDir(tscp1, cp, 0, &setAttr, userp, &req); if (code == 0 && (tscp1->flags & CM_SCACHEFLAG_ANYWATCH)) smb_NotifyChange(FILE_ACTION_ADDED, - FILE_NOTIFY_CHANGE_DIR_NAME, - tscp1, cp, NULL, TRUE); - if (code == 0 || - (code == CM_ERROR_EXISTS && createDisp != FILE_CREATE)) { + FILE_NOTIFY_CHANGE_DIR_NAME, + tscp1, cp, NULL, TRUE); + if (code == 0 || + (code == CM_ERROR_EXISTS && createDisp != FILE_CREATE)) { /* Not an exclusive create, and someone else tried * creating it already, then we open it anyway. We * don't bother retrying after this, since if this next @@ -7336,8 +7202,8 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) * started this call. */ code = cm_Lookup(tscp1, cp, CM_FLAG_CASEFOLD, - userp, &req, &tscp2); - } + userp, &req, &tscp2); + } if (code) break; @@ -7494,7 +7360,7 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) fidp->flags |= SMB_FID_NTOPEN; fidp->NTopen_dscp = dscp; dscp = NULL; - fidp->NTopen_pathp = strdup(lastNamep); + fidp->NTopen_pathp = cm_ClientStrDup(lastNamep); } fidp->NTopen_wholepathp = realPathp; lock_ReleaseMutex(&fidp->mx); @@ -7542,8 +7408,8 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) } lock_ReleaseRead(&scp->rw); - osi_Log2(smb_logp, "SMB NT CreateX opening fid %d path %s", fidp->fid, - osi_LogSaveString(smb_logp, realPathp)); + osi_Log2(smb_logp, "SMB NT CreateX opening fid %d path %S", fidp->fid, + osi_LogSaveClientString(smb_logp, realPathp)); cm_ReleaseUser(userp); smb_ReleaseFID(fidp); @@ -7563,7 +7429,7 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) /* NT_TRANSACT_CREATE (SMB_COM_NT_TRANSACT) */ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - char *pathp, *realPathp; + clientchar_t *pathp, *realPathp; long code = 0; cm_space_t *spacep; cm_user_t *userp; @@ -7571,7 +7437,7 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out cm_scache_t *scp; /* file to create or open */ cm_scache_t *targetScp; /* if scp is a symlink */ cm_attr_t setAttr; - char *lastNamep; + clientchar_t *lastNamep; unsigned long nameLength; unsigned int flags; unsigned int requestOpLock; @@ -7599,7 +7465,7 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out int parmSlot; long fidflags; FILETIME ft; - char *tidPathp; + clientchar_t *tidPathp; BOOL foundscp; int parmOffset, dataOffset; char *parmp; @@ -7669,14 +7535,14 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out if (extAttributes & SMB_ATTR_READONLY) initialModeBits &= ~0222; - pathp = parmp + (13 * sizeof(ULONG)) + sizeof(UCHAR); - pathp = smb_ParseStringCch(inp, pathp, nameLength, NULL, SMB_STRF_ANSIPATH); + pathp = smb_ParseStringCch(inp, (parmp + (13 * sizeof(ULONG)) + sizeof(UCHAR)), + nameLength, NULL, SMB_STRF_ANSIPATH); /* Sometimes path is not null-terminated, so we make a copy. */ - realPathp = malloc(nameLength+1); - memcpy(realPathp, pathp, nameLength); + realPathp = malloc((nameLength+1) * sizeof(clientchar_t)); + memcpy(realPathp, pathp, nameLength * sizeof(clientchar_t)); realPathp[nameLength] = 0; spacep = cm_GetSpace(); - smb_StripLastComponent(spacep->data, &lastNamep, realPathp); + smb_StripLastComponent(spacep->wdata, &lastNamep, realPathp); /* * Nothing here to handle SMB_IOCTL_FILENAME. @@ -7766,12 +7632,12 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out if ( createDisp == FILE_OPEN || createDisp == FILE_OVERWRITE || createDisp == FILE_OVERWRITE_IF) { - code = cm_NameI(baseDirp, spacep->data, CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, + code = cm_NameI(baseDirp, spacep->wdata, CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, userp, tidPathp, &req, &dscp); if (code == 0) { #ifdef DFS_SUPPORT if (dscp->fileType == CM_SCACHETYPE_DFSLINK) { - int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp, spacep->data); + int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp, spacep->wdata); cm_ReleaseSCache(dscp); cm_ReleaseUser(userp); free(realPathp); @@ -7825,12 +7691,12 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out if (code != 0 || (fidflags & (SMB_FID_OPENDELETE | SMB_FID_OPENWRITE))) { /* look up parent directory */ if ( !dscp ) { - code = cm_NameI(baseDirp, spacep->data, + code = cm_NameI(baseDirp, spacep->wdata, CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, userp, tidPathp, &req, &dscp); #ifdef DFS_SUPPORT if (code == 0 && dscp->fileType == CM_SCACHETYPE_DFSLINK) { - int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp, spacep->data); + int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp, spacep->wdata); cm_ReleaseSCache(dscp); cm_ReleaseUser(userp); free(realPathp); @@ -7961,8 +7827,8 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out } else if (realDirFlag == 0 || realDirFlag == -1) { osi_assertx(dscp != NULL, "null cm_scache_t"); - osi_Log1(smb_logp, "smb_ReceiveNTTranCreate creating file %s", - osi_LogSaveString(smb_logp, lastNamep)); + osi_Log1(smb_logp, "smb_ReceiveNTTranCreate creating file %S", + osi_LogSaveClientString(smb_logp, lastNamep)); openAction = 2; /* created file */ setAttr.mask = CM_ATTRMASK_CLIENTMODTIME; setAttr.clientModTime = time(NULL); @@ -8013,8 +7879,8 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out /* create directory */ osi_assertx(dscp != NULL, "null cm_scache_t"); osi_Log1(smb_logp, - "smb_ReceiveNTTranCreate creating directory %s", - osi_LogSaveString(smb_logp, lastNamep)); + "smb_ReceiveNTTranCreate creating directory %S", + osi_LogSaveClientString(smb_logp, lastNamep)); openAction = 2; /* created directory */ setAttr.mask = CM_ATTRMASK_CLIENTMODTIME; setAttr.clientModTime = time(NULL); @@ -8160,7 +8026,7 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out fidp->NTopen_dscp = dscp; osi_Log2(smb_logp,"smb_ReceiveNTTranCreate fidp 0x%p dscp 0x%p", fidp, dscp); dscp = NULL; - fidp->NTopen_pathp = strdup(lastNamep); + fidp->NTopen_pathp = cm_ClientStrDup(lastNamep); } fidp->NTopen_wholepathp = realPathp; lock_ReleaseMutex(&fidp->mx); @@ -8340,8 +8206,8 @@ long smb_ReceiveNTTranNotifyChange(smb_vc_t *vcp, smb_packet_t *inp, lock_ReleaseMutex(&smb_Dir_Watch_Lock); scp = fidp->scp; - osi_Log3(smb_logp,"smb_ReceiveNTTranNotifyChange fidp 0x%p scp 0x%p file \"%s\"", - fidp, scp, osi_LogSaveString(smb_logp, fidp->NTopen_wholepathp)); + osi_Log3(smb_logp,"smb_ReceiveNTTranNotifyChange fidp 0x%p scp 0x%p file \"%S\"", + fidp, scp, osi_LogSaveClientString(smb_logp, fidp->NTopen_wholepathp)); osi_Log3(smb_logp, "Request for NotifyChange filter 0x%x fid %d wtree %d", filter, fid, watchtree); if (filter & FILE_NOTIFY_CHANGE_FILE_NAME) @@ -8518,11 +8384,11 @@ long smb_ReceiveNTTransact(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) * has the isDirectParent parameter set to FALSE. */ void smb_NotifyChange(DWORD action, DWORD notifyFilter, - cm_scache_t *dscp, char *filename, char *otherFilename, + cm_scache_t *dscp, clientchar_t *filename, clientchar_t *otherFilename, BOOL isDirectParent) { smb_packet_t *watch, *lastWatch, *nextWatch; - ULONG parmSlot, parmCount, parmOffset, dataOffset, nameLen; + ULONG parmSlot, parmCount, parmOffset, dataOffset, nameLen = 0; char *outData, *oldOutData; ULONG filter; USHORT fid, wtree; @@ -8538,8 +8404,8 @@ void smb_NotifyChange(DWORD action, DWORD notifyFilter, otherAction = FILE_ACTION_RENAMED_NEW_NAME; } - osi_Log4(smb_logp,"in smb_NotifyChange for file [%s] dscp [%p] notification 0x%x parent %d", - osi_LogSaveString(smb_logp,filename),dscp, notifyFilter, isDirectParent); + osi_Log4(smb_logp,"in smb_NotifyChange for file [%S] dscp [%p] notification 0x%x parent %d", + osi_LogSaveClientString(smb_logp,filename),dscp, notifyFilter, isDirectParent); if (action == 0) osi_Log0(smb_logp," FILE_ACTION_NONE"); if (action == FILE_ACTION_ADDED) @@ -8592,8 +8458,8 @@ void smb_NotifyChange(DWORD action, DWORD notifyFilter, smb_ReleaseFID(fidp); osi_Log4(smb_logp, - "Sending Change Notification for fid %d filter 0x%x wtree %d file %s", - fid, filter, wtree, osi_LogSaveString(smb_logp, filename)); + "Sending Change Notification for fid %d filter 0x%x wtree %d file %S", + fid, filter, wtree, osi_LogSaveClientString(smb_logp, filename)); if (filter & FILE_NOTIFY_CHANGE_FILE_NAME) osi_Log0(smb_logp, " Notify Change File Name"); if (filter & FILE_NOTIFY_CHANGE_DIR_NAME) @@ -8642,14 +8508,14 @@ void smb_NotifyChange(DWORD action, DWORD notifyFilter, ((smb_t *) watch)->wct = 0; /* out parms */ - if (filename == NULL) + if (filename == NULL) { parmCount = 0; - else { - nameLen = (ULONG)strlen(filename); + } else { + nameLen = (ULONG)cm_ClientStrLen(filename); parmCount = 3*4 + nameLen*2; parmCount = (parmCount + 3) & ~3; /* pad to 4 */ if (twoEntries) { - otherNameLen = (ULONG)strlen(otherFilename); + otherNameLen = (ULONG)cm_ClientStrLen(otherFilename); oldParmCount = parmCount; parmCount += 3*4 + otherNameLen*2; parmCount = (parmCount + 3) & ~3; /* pad to 4 */ @@ -8683,7 +8549,6 @@ void smb_NotifyChange(DWORD action, DWORD notifyFilter, smb_SetSMBDataLength(watch, parmCount + 1); if (parmCount != 0) { - char * p; outData = smb_GetSMBData(watch, NULL); outData++; /* round to get to parmOffset */ oldOutData = outData; @@ -8693,12 +8558,10 @@ void smb_NotifyChange(DWORD action, DWORD notifyFilter, /* Action */ *((DWORD *)outData) = nameLen*2; outData += 4; /* File Name Length */ - p = strdup(filename); - if (smb_StoreAnsiFilenames) - CharToOem(p,p); - mbstowcs((WCHAR *)outData, p, nameLen); - free(p); + + smb_UnparseString(watch, outData, filename, NULL, 0); /* File Name */ + if (twoEntries) { outData = oldOutData + oldParmCount; *((DWORD *)outData) = 0; outData += 4; @@ -8707,13 +8570,9 @@ void smb_NotifyChange(DWORD action, DWORD notifyFilter, /* Action */ *((DWORD *)outData) = otherNameLen*2; outData += 4; /* File Name Length */ - p = strdup(otherFilename); - if (smb_StoreAnsiFilenames) - CharToOem(p,p); - mbstowcs((WCHAR *)outData, p, otherNameLen); /* File Name */ - free(p); + smb_UnparseString(watch, outData, otherFilename, NULL, 0); } - } + } /* * If filename is null, we don't know the cause of the @@ -8772,9 +8631,9 @@ long smb_ReceiveNTCancel(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) fidp = smb_FindFID(vcp, fid, 0); if (fidp) { - osi_Log3(smb_logp, "Cancelling change notification for fid %d wtree %d file %s", - fid, watchtree, - osi_LogSaveString(smb_logp, (fidp)?fidp->NTopen_wholepathp:"")); + osi_Log3(smb_logp, "Cancelling change notification for fid %d wtree %d file %S", + fid, watchtree, + (fidp ? osi_LogSaveClientString(smb_logp, fidp->NTopen_wholepathp) :_C(""))); scp = fidp->scp; osi_Log2(smb_logp,"smb_ReceiveNTCancel fidp 0x%p scp 0x%p", fidp, scp); @@ -8822,7 +8681,7 @@ long smb_ReceiveNTCancel(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) long smb_ReceiveNTRename(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - char *oldPathp, *newPathp; + clientchar_t *oldPathp, *newPathp; long code = 0; char * tp; int attrs; @@ -8840,9 +8699,9 @@ long smb_ReceiveNTRename(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) oldPathp = smb_ParseASCIIBlock(inp, tp, &tp, 0); newPathp = smb_ParseASCIIBlock(inp, tp, &tp, 0); - osi_Log3(smb_logp, "NTRename for [%s]->[%s] type [%s]", - osi_LogSaveString(smb_logp, oldPathp), - osi_LogSaveString(smb_logp, newPathp), + osi_Log3(smb_logp, "NTRename for [%S]->[%S] type [%s]", + osi_LogSaveClientString(smb_logp, oldPathp), + osi_LogSaveClientString(smb_logp, newPathp), ((rename_type==RENAME_FLAG_RENAME)?"rename":"hardlink")); if (rename_type == RENAME_FLAG_RENAME) { @@ -8858,7 +8717,7 @@ void smb3_Init() lock_InitializeMutex(&smb_Dir_Watch_Lock, "Directory Watch List Lock"); } -cm_user_t *smb_FindCMUserByName(char *usern, char *machine, afs_uint32 flags) +cm_user_t *smb_FindCMUserByName(clientchar_t *usern, clientchar_t *machine, afs_uint32 flags) { smb_username_t *unp; cm_user_t * userp; @@ -8868,9 +8727,9 @@ cm_user_t *smb_FindCMUserByName(char *usern, char *machine, afs_uint32 flags) lock_ObtainMutex(&unp->mx); unp->userp = cm_NewUser(); lock_ReleaseMutex(&unp->mx); - osi_Log2(smb_logp,"smb_FindCMUserByName New user name[%s] machine[%s]",osi_LogSaveString(smb_logp,usern),osi_LogSaveString(smb_logp,machine)); + osi_Log2(smb_logp,"smb_FindCMUserByName New user name[%S] machine[%S]",osi_LogSaveClientString(smb_logp,usern),osi_LogSaveClientString(smb_logp,machine)); } else { - osi_Log2(smb_logp,"smb_FindCMUserByName Not found name[%s] machine[%s]",osi_LogSaveString(smb_logp,usern),osi_LogSaveString(smb_logp,machine)); + osi_Log2(smb_logp,"smb_FindCMUserByName Not found name[%S] machine[%S]",osi_LogSaveClientString(smb_logp,usern),osi_LogSaveClientString(smb_logp,machine)); } userp = unp->userp; cm_HoldUser(userp); diff --git a/src/WINNT/afsd/smb3.h b/src/WINNT/afsd/smb3.h index 99209df..23818d3 100644 --- a/src/WINNT/afsd/smb3.h +++ b/src/WINNT/afsd/smb3.h @@ -389,17 +389,16 @@ extern long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t extern long smb_ReceiveNTTransact(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp); extern void smb_NotifyChange(DWORD action, DWORD notifyFilter, - cm_scache_t *dscp, char *filename, char *otherFilename, + cm_scache_t *dscp, clientchar_t *filename, clientchar_t *otherFilename, BOOL isDirectParent); extern long smb_ReceiveNTCancel(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp); extern long smb_ReceiveNTRename(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp); -extern int smb_V3MatchMask(char *namep, char *maskp, int flags); +extern unsigned long smb_ExtAttributes(cm_scache_t *scp); extern void smb3_Init(); -extern cm_user_t *smb_FindCMUserByName(char *usern, char *machine, afs_uint32 flags); /* SMB auth related functions */ extern void smb_NegotiateExtendedSecurity(void ** secBlob, int * secBlobLength); diff --git a/src/WINNT/afsd/smb_ioctl.c b/src/WINNT/afsd/smb_ioctl.c index 7729816..739f81c 100644 --- a/src/WINNT/afsd/smb_ioctl.c +++ b/src/WINNT/afsd/smb_ioctl.c @@ -119,7 +119,7 @@ smb_SetupIoctlFid(smb_fid_t *fidp, cm_space_t *prefix) * call to the ioctl code. */ afs_int32 -smb_IoctlPrepareRead(smb_fid_t *fidp, smb_ioctl_t *ioctlp, cm_user_t *userp) +smb_IoctlPrepareRead(struct smb_fid *fidp, smb_ioctl_t *ioctlp, cm_user_t *userp) { afs_int32 opcode; smb_ioctlProc_t *procp = NULL; @@ -353,9 +353,9 @@ smb_IoctlV3Read(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t osi_assertx(userp != NULL, "null cm_user_t"); iop->uidp = uidp; if (uidp && uidp->unp) { - osi_Log3(afsd_logp, "Ioctl uid %d user %x name %s", - uidp->userID, userp, - osi_LogSaveString(afsd_logp, uidp->unp->name)); + osi_Log3(afsd_logp, "Ioctl uid %d user %x name %S", + uidp->userID, userp, + osi_LogSaveClientString(afsd_logp, uidp->unp->name)); } else { if (uidp) osi_Log2(afsd_logp, "Ioctl uid %d user %x no name", @@ -444,11 +444,11 @@ smb_IoctlReadRaw(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp, uidp = smb_FindUID(vcp, ((smb_t *)inp)->uid, 0); if (uidp && uidp->unp) { osi_Log3(afsd_logp, "Ioctl uid %d user %x name %s", - uidp->userID, userp, - osi_LogSaveString(afsd_logp, uidp->unp->name)); + uidp->userID, userp, + osi_LogSaveClientString(afsd_logp, uidp->unp->name)); } else if (uidp) { osi_Log2(afsd_logp, "Ioctl uid %d user %x no name", - uidp->userID, userp); + uidp->userID, userp); } else { osi_Log1(afsd_logp, "Ioctl no uid user %x no name", userp); @@ -499,33 +499,33 @@ afs_int32 smb_ParseIoctlPath(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp, cm_scache_t **scpp, afs_uint32 flags) { - afs_int32 code; - cm_scache_t *substRootp = NULL; - cm_scache_t *iscp = NULL; - char * relativePath; - char * lastComponent = NULL; + long code; + cm_scache_t *substRootp = NULL; + cm_scache_t *iscp = NULL; + char *inPath; + clientchar_t *relativePath = NULL; + clientchar_t *lastComponent = NULL; afs_uint32 follow = (flags & CM_PARSE_FLAG_LITERAL ? CM_FLAG_NOMOUNTCHASE : CM_FLAG_FOLLOW); - int free_path = FALSE; - relativePath = ioctlp->ioctl.inDatap; + inPath = ioctlp->ioctl.inDatap; /* setup the next data value for the caller to use */ - ioctlp->ioctl.inDatap += (long)strlen(ioctlp->ioctl.inDatap) + 1;; + ioctlp->ioctl.inDatap += (long)strlen(ioctlp->ioctl.inDatap) + 1; - osi_Log1(afsd_logp, "smb_ParseIoctlPath %s", osi_LogSaveString(afsd_logp,relativePath)); + osi_Log1(afsd_logp, "cm_ParseIoctlPath %s", osi_LogSaveString(afsd_logp,inPath)); /* This is usually the file name, but for StatMountPoint it is the path. */ - /* ioctlp->inDatap can be either of the form: + /* ioctlp->ioctl.inDatap can be either of the form: * \path\. * \path\file * \\netbios-name\submount\path\. * \\netbios-name\submount\path\file */ - /* We do not perform path name translation on the ioctl path data - * because these paths were not translated by Windows through the - * file system API. Therefore, they are not OEM characters but - * whatever the display character set is. - */ + /* We do not perform path name translation on the ioctl path data + * because these paths were not translated by Windows through the + * file system API. Therefore, they are not OEM characters but + * whatever the display character set is. + */ // TranslateExtendedChars(relativePath); @@ -538,41 +538,44 @@ smb_ParseIoctlPath(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp, we have to convert the string to UTF-8, since that is what we want to use everywhere else.*/ - if (memcmp(relativePath, utf8_prefix, utf8_prefix_size) == 0) { - int len, normalized_len; - char * normalized_path; - + if (memcmp(inPath, utf8_prefix, utf8_prefix_size) == 0) { /* String is UTF-8 */ - relativePath += utf8_prefix_size; + inPath += utf8_prefix_size; ioctlp->ioctl.flags |= CM_IOCTLFLAG_USEUTF8; - len = (ioctlp->ioctl.inDatap - relativePath); - - normalized_len = cm_NormalizeUtf8String(relativePath, len, NULL, 0); - - if (normalized_len > len) { - normalized_path = malloc(normalized_len); - free_path = TRUE; - } else { - normalized_path = relativePath; - } - - cm_NormalizeUtf8String(relativePath, len, normalized_path, normalized_len); - - if (normalized_path != relativePath) - relativePath = normalized_path; + relativePath = cm_Utf8ToClientStringAlloc(inPath, -1, NULL); } else { + int cch; + /* Not a UTF-8 string */ /* TODO: If this is an OEM string, we should convert it to UTF-8. */ + if (smb_StoreAnsiFilenames) { + cch = cm_AnsiToClientString(inPath, -1, NULL, 0); +#ifdef DEBUG + osi_assert(cch > 0); +#endif + relativePath = malloc(cch * sizeof(clientchar_t)); + cm_AnsiToClientString(inPath, -1, relativePath, cch); + } else { + TranslateExtendedChars(inPath); + + cch = cm_OemToClientString(inPath, -1, NULL, 0); +#ifdef DEBUG + osi_assert(cch > 0); +#endif + relativePath = malloc(cch * sizeof(clientchar_t)); + cm_OemToClientString(inPath, -1, relativePath, cch); + } } if (relativePath[0] == relativePath[1] && - relativePath[1] == '\\' && - !_strnicmp(cm_NetbiosName,relativePath+2,strlen(cm_NetbiosName))) + relativePath[1] == '\\' && + !cm_ClientStrCmpNI(cm_NetbiosNameC, relativePath+2, + cm_ClientStrLen(cm_NetbiosNameC))) { - char shareName[256]; - char *sharePath; + clientchar_t shareName[256]; + clientchar_t *sharePath; int shareFound, i; /* We may have found a UNC path. @@ -580,9 +583,9 @@ smb_ParseIoctlPath(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp, * then throw out the second component (the submount) * since it had better expand into the value of ioctl->tidPathp */ - char * p; - p = relativePath + 2 + strlen(cm_NetbiosName) + 1; /* buffer overflow vuln.? */ - if ( !_strnicmp("all", p, 3) ) + clientchar_t * p; + p = relativePath + 2 + cm_ClientStrLen(cm_NetbiosNameC) + 1; /* buffer overflow vuln.? */ + if ( !cm_ClientStrCmpNI(_C("all"), p, 3) ) p += 4; for (i = 0; *p && *p != '\\'; i++,p++ ) { @@ -594,24 +597,25 @@ smb_ParseIoctlPath(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp, shareFound = smb_FindShare(ioctlp->fidp->vcp, ioctlp->uidp, shareName, &sharePath); if ( shareFound ) { /* we found a sharename, therefore use the resulting path */ - code = cm_NameI(cm_data.rootSCachep, ioctlp->prefix->data, - CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, - userp, sharePath, reqp, &substRootp); + code = cm_NameI(cm_data.rootSCachep, ioctlp->prefix->wdata, + CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, + userp, sharePath, reqp, &substRootp); free(sharePath); if (code) { - osi_Log1(afsd_logp,"smb_ParseIoctlPath [1] code 0x%x", code); - if (free_path) + osi_Log1(afsd_logp,"cm_ParseIoctlPath [1] code 0x%x", code); + if (relativePath) free(relativePath); return code; } - lastComponent = strrchr(p, '\\'); - if (lastComponent && (lastComponent - p) > 1 &&strlen(lastComponent) > 1) { + lastComponent = cm_ClientStrRChr(p, '\\'); + if (lastComponent && (lastComponent - p) > 1 && + cm_ClientStrLen(lastComponent) > 1) { *lastComponent = '\0'; lastComponent++; code = cm_NameI(substRootp, p, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, - userp, NULL, reqp, &iscp); + userp, NULL, reqp, &iscp); if (code == 0) code = cm_NameI(iscp, lastComponent, CM_FLAG_CASEFOLD | follow, userp, NULL, reqp, scpp); @@ -623,8 +627,8 @@ smb_ParseIoctlPath(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp, } cm_ReleaseSCache(substRootp); if (code) { - osi_Log1(afsd_logp,"smb_ParseIoctlPath [2] code 0x%x", code); - if (free_path) + osi_Log1(afsd_logp,"cm_ParseIoctlPath [2] code 0x%x", code); + if (relativePath) free(relativePath); return code; } @@ -633,8 +637,8 @@ smb_ParseIoctlPath(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp, * This requires that we reconstruct the shareName string with * leading and trailing slashes. */ - p = relativePath + 2 + strlen(cm_NetbiosName) + 1; - if ( !_strnicmp("all", p, 3) ) + p = relativePath + 2 + cm_ClientStrLen(cm_NetbiosNameC) + 1; + if ( !cm_ClientStrCmpNI(_C("all"), p, 3) ) p += 4; shareName[0] = '/'; @@ -646,23 +650,24 @@ smb_ParseIoctlPath(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp, shareName[i] = 0; /* terminate string */ - code = cm_NameI(cm_data.rootSCachep, ioctlp->prefix->data, - CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, - userp, shareName, reqp, &substRootp); + code = cm_NameI(cm_data.rootSCachep, ioctlp->prefix->wdata, + CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, + userp, shareName, reqp, &substRootp); if (code) { - osi_Log1(afsd_logp,"smb_ParseIoctlPath [3] code 0x%x", code); - if (free_path) + osi_Log1(afsd_logp,"cm_ParseIoctlPath [3] code 0x%x", code); + if (relativePath) free(relativePath); return code; } - lastComponent = strrchr(p, '\\'); - if (lastComponent && (lastComponent - p) > 1 &&strlen(lastComponent) > 1) { + lastComponent = cm_ClientStrRChr(p, '\\'); + if (lastComponent && (lastComponent - p) > 1 && + cm_ClientStrLen(lastComponent) > 1) { *lastComponent = '\0'; lastComponent++; code = cm_NameI(substRootp, p, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, - userp, NULL, reqp, &iscp); + userp, NULL, reqp, &iscp); if (code == 0) code = cm_NameI(iscp, lastComponent, CM_FLAG_CASEFOLD | follow, userp, NULL, reqp, scpp); @@ -675,43 +680,44 @@ smb_ParseIoctlPath(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp, if (code) { cm_ReleaseSCache(substRootp); - osi_Log1(afsd_logp,"smb_ParseIoctlPath code [4] 0x%x", code); - if (free_path) + osi_Log1(afsd_logp,"cm_ParseIoctlPath code [4] 0x%x", code); + if (relativePath) free(relativePath); return code; } } } else { - code = cm_NameI(cm_data.rootSCachep, ioctlp->prefix->data, + code = cm_NameI(cm_data.rootSCachep, ioctlp->prefix->wdata, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, userp, ioctlp->tidPathp, reqp, &substRootp); if (code) { - osi_Log1(afsd_logp,"smb_ParseIoctlPath [6] code 0x%x", code); - if (free_path) + osi_Log1(afsd_logp,"cm_ParseIoctlPath [6] code 0x%x", code); + if (relativePath) free(relativePath); return code; } - lastComponent = strrchr(relativePath, '\\'); - if (lastComponent && (lastComponent - relativePath) > 1 && strlen(lastComponent) > 1) { + lastComponent = cm_ClientStrRChr(relativePath, '\\'); + if (lastComponent && (lastComponent - relativePath) > 1 && + cm_ClientStrLen(lastComponent) > 1) { *lastComponent = '\0'; lastComponent++; code = cm_NameI(substRootp, relativePath, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, - userp, NULL, reqp, &iscp); + userp, NULL, reqp, &iscp); if (code == 0) code = cm_NameI(iscp, lastComponent, CM_FLAG_CASEFOLD | follow, - userp, NULL, reqp, scpp); + userp, NULL, reqp, scpp); if (iscp) cm_ReleaseSCache(iscp); } else { code = cm_NameI(substRootp, relativePath, CM_FLAG_CASEFOLD | follow, - userp, NULL, reqp, scpp); + userp, NULL, reqp, scpp); } if (code) { cm_ReleaseSCache(substRootp); - osi_Log1(afsd_logp,"smb_ParseIoctlPath [7] code 0x%x", code); - if (free_path) + osi_Log1(afsd_logp,"cm_ParseIoctlPath [7] code 0x%x", code); + if (relativePath) free(relativePath); return code; } @@ -721,9 +727,9 @@ smb_ParseIoctlPath(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp, cm_ReleaseSCache(substRootp); /* and return success */ - osi_Log1(afsd_logp,"smb_ParseIoctlPath [8] code 0x%x", code); + osi_Log1(afsd_logp,"cm_ParseIoctlPath [8] code 0x%x", code); - if (free_path) + if (relativePath) free(relativePath); return 0; } @@ -736,16 +742,16 @@ smb_ParseIoctlPath(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp, */ afs_int32 smb_ParseIoctlParent(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp, - cm_scache_t **scpp, char *leafp) + cm_scache_t **scpp, clientchar_t *leafp) { - afs_int32 code; - char tbuffer[1024]; - char *tp, *jp; + long code; + clientchar_t tbuffer[1024]; + clientchar_t *tp, *jp; cm_scache_t *substRootp = NULL; - char *inpathp; - int free_path = FALSE; + clientchar_t *inpathp = NULL; + char *inpathdatap; - inpathp = ioctlp->ioctl.inDatap; + inpathdatap = ioctlp->ioctl.inDatap; /* If the string starts with our UTF-8 prefix (which is the sequence [ESC,'%','G'] as used by ISO-2022 to designate UTF-8 @@ -753,67 +759,66 @@ smb_ParseIoctlParent(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp, we have to convert the string to UTF-8, since that is what we want to use everywhere else.*/ - if (memcmp(inpathp, utf8_prefix, utf8_prefix_size) == 0) { - int len, normalized_len; - char * normalized_path; + if (memcmp(inpathdatap, utf8_prefix, utf8_prefix_size) == 0) { /* String is UTF-8 */ - inpathp += utf8_prefix_size; + inpathdatap += utf8_prefix_size; ioctlp->ioctl.flags |= CM_IOCTLFLAG_USEUTF8; - len = strlen(inpathp) + 1; - - normalized_len = cm_NormalizeUtf8String(inpathp, len, NULL, 0); - - if (normalized_len > len) { - normalized_path = malloc(normalized_len); - free_path = TRUE; - } else { - normalized_path = inpathp; - } - - cm_NormalizeUtf8String(inpathp, len, normalized_path, normalized_len); - - if (normalized_path != inpathp) - inpathp = normalized_path; + inpathp = cm_Utf8ToClientStringAlloc(inpathdatap, -1, NULL); } else { + int cch; + /* Not a UTF-8 string */ /* TODO: If this is an OEM string, we should convert it to UTF-8. */ + if (smb_StoreAnsiFilenames) { + cch = cm_AnsiToClientString(inpathdatap, -1, NULL, 0); +#ifdef DEBUG + osi_assert(cch > 0); +#endif + inpathp = malloc(cch * sizeof(clientchar_t)); + cm_AnsiToClientString(inpathdatap, -1, inpathp, cch); + } else { + TranslateExtendedChars(inpathdatap); + + cch = cm_OemToClientString(inpathdatap, -1, NULL, 0); +#ifdef DEBUG + osi_assert(cch > 0); +#endif + inpathp = malloc(cch * sizeof(clientchar_t)); + cm_OemToClientString(inpathdatap, -1, inpathp, cch); + } } - StringCbCopyA(tbuffer, sizeof(tbuffer), inpathp); - tp = strrchr(tbuffer, '\\'); - jp = strrchr(tbuffer, '/'); + cm_ClientStrCpy(tbuffer, lengthof(tbuffer), inpathp); + tp = cm_ClientStrRChr(tbuffer, '\\'); + jp = cm_ClientStrRChr(tbuffer, '/'); if (!tp) tp = jp; else if (jp && (tp - tbuffer) < (jp - tbuffer)) tp = jp; if (!tp) { - StringCbCopyA(tbuffer, sizeof(tbuffer), "\\"); - if (leafp) - StringCbCopyA(leafp, LEAF_SIZE, inpathp); + cm_ClientStrCpy(tbuffer, lengthof(tbuffer), _C("\\")); + if (leafp) + cm_ClientStrCpy(leafp, LEAF_SIZE, inpathp); } else { *tp = 0; if (leafp) - StringCbCopyA(leafp, LEAF_SIZE, tp+1); - } - - if (free_path) - free(inpathp); - inpathp = NULL; /* We don't need this from this point on */ + cm_ClientStrCpy(leafp, LEAF_SIZE, tp+1); + } - if (free_path) - free(inpathp); + free(inpathp); inpathp = NULL; /* We don't need this from this point on */ if (tbuffer[0] == tbuffer[1] && tbuffer[1] == '\\' && - !_strnicmp(cm_NetbiosName,tbuffer+2,strlen(cm_NetbiosName))) + !cm_ClientStrCmpNI(cm_NetbiosNameC, tbuffer+2, + cm_ClientStrLen(cm_NetbiosNameC))) { - char shareName[256]; - char *sharePath; + clientchar_t shareName[256]; + clientchar_t *sharePath; int shareFound, i; /* We may have found a UNC path. @@ -821,9 +826,9 @@ smb_ParseIoctlParent(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp, * then throw out the second component (the submount) * since it had better expand into the value of ioctl->tidPathp */ - char * p; - p = tbuffer + 2 + strlen(cm_NetbiosName) + 1; - if ( !_strnicmp("all", p, 3) ) + clientchar_t * p; + p = tbuffer + 2 + cm_ClientStrLen(cm_NetbiosNameC) + 1; + if ( !cm_ClientStrCmpNI(_C("all"), p, 3) ) p += 4; for (i = 0; *p && *p != '\\'; i++,p++ ) { @@ -835,14 +840,14 @@ smb_ParseIoctlParent(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp, shareFound = smb_FindShare(ioctlp->fidp->vcp, ioctlp->uidp, shareName, &sharePath); if ( shareFound ) { /* we found a sharename, therefore use the resulting path */ - code = cm_NameI(cm_data.rootSCachep, ioctlp->prefix->data, - CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, - userp, sharePath, reqp, &substRootp); + code = cm_NameI(cm_data.rootSCachep, ioctlp->prefix->wdata, + CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, + userp, sharePath, reqp, &substRootp); free(sharePath); if (code) return code; code = cm_NameI(substRootp, p, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, - userp, NULL, reqp, scpp); + userp, NULL, reqp, scpp); cm_ReleaseSCache(substRootp); if (code) return code; } else { @@ -850,8 +855,8 @@ smb_ParseIoctlParent(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp, * This requires that we reconstruct the shareName string with * leading and trailing slashes. */ - p = tbuffer + 2 + strlen(cm_NetbiosName) + 1; - if ( !_strnicmp("all", p, 3) ) + p = tbuffer + 2 + cm_ClientStrLen(cm_NetbiosNameC) + 1; + if ( !cm_ClientStrCmpNI(_C("all"), p, 3) ) p += 4; shareName[0] = '/'; @@ -862,9 +867,9 @@ smb_ParseIoctlParent(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp, shareName[i++] = '/'; /* add trailing slash */ shareName[i] = 0; /* terminate string */ - code = cm_NameI(cm_data.rootSCachep, ioctlp->prefix->data, - CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, - userp, shareName, reqp, &substRootp); + code = cm_NameI(cm_data.rootSCachep, ioctlp->prefix->wdata, + CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, + userp, shareName, reqp, &substRootp); if (code) return code; code = cm_NameI(substRootp, p, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, @@ -873,7 +878,7 @@ smb_ParseIoctlParent(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp, if (code) return code; } } else { - code = cm_NameI(cm_data.rootSCachep, ioctlp->prefix->data, + code = cm_NameI(cm_data.rootSCachep, ioctlp->prefix->wdata, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, userp, ioctlp->tidPathp, reqp, &substRootp); if (code) return code; @@ -903,13 +908,14 @@ smb_IoctlSetToken(struct smb_ioctl *ioctlp, struct cm_user *userp) struct ClearToken ct; cm_cell_t *cellp; cm_ucell_t *ucellp; - char *uname = NULL; afs_uuid_t uuid; int flags; char sessionKey[8]; - char *smbname; int release_userp = 0; - char * wdir = NULL; + clientchar_t *uname = NULL; + clientchar_t *smbname = NULL; + clientchar_t *wdir = NULL; + afs_int32 code = 0; saveDataPtr = ioctlp->ioctl.inDatap; @@ -946,31 +952,46 @@ smb_IoctlSetToken(struct smb_ioctl *ioctlp, struct cm_user *userp) tp += sizeof(int); /* cell name */ - cellp = cm_GetCell(tp, CM_FLAG_CREATE | CM_FLAG_NOPROBE); - if (!cellp) - return CM_ERROR_NOSUCHCELL; + { + fschar_t * cellnamep; + clientchar_t * temp; + + temp = cm_ParseIoctlStringAlloc(&ioctlp->ioctl, tp); + cellnamep = cm_ClientStringToFsStringAlloc(temp, -1, NULL); + cellp = cm_GetCell(cellnamep, CM_FLAG_CREATE | CM_FLAG_NOPROBE); + free(cellnamep); + free(temp); + } + + if (!cellp) { + code = CM_ERROR_NOSUCHCELL; + goto done; + } tp += strlen(tp) + 1; /* user name */ - uname = tp; + uname = cm_ParseIoctlStringAlloc(&ioctlp->ioctl, tp); tp += strlen(tp) + 1; 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]", - osi_LogSaveString(smb_logp,uname), osi_LogSaveString(smb_logp,smbname)); - fprintf(stderr, "SMB name = %s\n", smbname); + smbname = cm_ParseIoctlStringAlloc(&ioctlp->ioctl, tp); + osi_Log2(smb_logp,"cm_IoctlSetToken for user [%S] smbname [%S]", + osi_LogSaveClientString(smb_logp,uname), + osi_LogSaveClientString(smb_logp,smbname)); + fprintf(stderr, "SMB name = %S\n", smbname); tp += strlen(tp) + 1; } else { - osi_Log1(smb_logp,"cm_IoctlSetToken for user [%s]", - osi_LogSaveString(smb_logp, uname)); + osi_Log1(smb_logp,"cm_IoctlSetToken for user [%S]", + osi_LogSaveClientString(smb_logp, uname)); } - /* uuid */ + /* uuid */ memcpy(&uuid, tp, sizeof(uuid)); - if (!cm_FindTokenEvent(uuid, sessionKey)) - return CM_ERROR_INVAL; + if (!cm_FindTokenEvent(uuid, sessionKey)) { + code = CM_ERROR_INVAL; + goto done; + } } else { cellp = cm_data.rootCellp; osi_Log0(smb_logp,"cm_IoctlSetToken - no name specified"); @@ -1005,7 +1026,7 @@ smb_IoctlSetToken(struct smb_ioctl *ioctlp, struct cm_user *userp) ucellp->uid = ANONYMOUSID; #endif if (uname) { - StringCbCopyA(ucellp->userName, MAXKTCNAMELEN, uname); + cm_ClientStringToFsString(uname, -1, ucellp->userName, MAXKTCNAMELEN); #ifdef QUERY_AFSID cm_UsernameToId(uname, ucellp, &ucellp->uid); #endif @@ -1019,10 +1040,17 @@ smb_IoctlSetToken(struct smb_ioctl *ioctlp, struct cm_user *userp) cm_ResetACLCache(userp); + done: if (release_userp) cm_ReleaseUser(userp); - return 0; + if (uname) + free(uname); + + if (smbname) + free(smbname); + + return code; } @@ -1033,8 +1061,17 @@ smb_IoctlGetSMBName(smb_ioctl_t *ioctlp, cm_user_t *userp) smb_user_t *uidp = ioctlp->uidp; if (uidp && uidp->unp) { - memcpy(ioctlp->ioctl.outDatap, uidp->unp->name, strlen(uidp->unp->name)); - ioctlp->ioctl.outDatap += strlen(uidp->unp->name); + int cch; + + cch = cm_ClientStringToUtf8(uidp->unp->name, + cm_ClientStrLen(uidp->unp->name), + + ioctlp->ioctl.outDatap, + (SMB_IOCTL_MAXDATA - + (ioctlp->ioctl.outDatap - ioctlp->ioctl.outAllocp)) + / sizeof(cm_utf8char_t)); + + ioctlp->ioctl.outDatap += cch * sizeof(cm_utf8char_t); } return 0; @@ -1561,13 +1598,13 @@ smb_IoctlCreateMountPoint(struct smb_ioctl *ioctlp, struct cm_user *userp) { afs_int32 code; cm_scache_t *dscp; - char leaf[LEAF_SIZE]; + clientchar_t leaf[LEAF_SIZE]; cm_req_t req; cm_InitReq(&req); code = smb_ParseIoctlParent(ioctlp, userp, &req, &dscp, leaf); - if (code) + if (code) return code; code = cm_IoctlCreateMountPoint(&ioctlp->ioctl, userp, dscp, &req, leaf); @@ -1581,7 +1618,7 @@ smb_IoctlSymlink(struct smb_ioctl *ioctlp, struct cm_user *userp) { afs_int32 code; cm_scache_t *dscp; - char leaf[LEAF_SIZE]; + clientchar_t leaf[LEAF_SIZE]; cm_req_t req; cm_InitReq(&req); diff --git a/src/WINNT/afsd/smb_ioctl.h b/src/WINNT/afsd/smb_ioctl.h index a9f0c82..202f5dc 100644 --- a/src/WINNT/afsd/smb_ioctl.h +++ b/src/WINNT/afsd/smb_ioctl.h @@ -11,6 +11,7 @@ #define __SMB_IOCTL_H_ENV__ 1 #include +#include /* magic file name for ioctl opens */ #define SMB_IOCTL_FILENAME CM_IOCTL_FILENAME @@ -33,8 +34,8 @@ typedef struct smb_ioctl { struct smb_user *uidp; /* pathname associated with the Tree ID */ - char *tidPathp; - + clientchar_t *tidPathp; + /* prefix for subst drives */ cm_space_t *prefix; @@ -44,28 +45,42 @@ typedef struct smb_ioctl { /* procedure implementing an ioctl */ typedef long (smb_ioctlProc_t)(smb_ioctl_t *, struct cm_user *userp); -extern void smb_InitIoctl(void); +extern void +smb_InitIoctl(void); -extern void smb_SetupIoctlFid(struct smb_fid *fidp, cm_space_t *prefix); +extern void +smb_SetupIoctlFid(struct smb_fid *fidp, cm_space_t *prefix); -extern afs_int32 smb_IoctlRead(struct smb_fid *fidp, struct smb_vc *vcp, struct smb_packet *inp, struct smb_packet *outp); +extern afs_int32 +smb_IoctlRead(struct smb_fid *fidp, struct smb_vc *vcp, + struct smb_packet *inp, struct smb_packet *outp); -extern afs_int32 smb_IoctlWrite(struct smb_fid *fidp, struct smb_vc *vcp, struct smb_packet *inp, struct smb_packet *outp); +extern afs_int32 +smb_IoctlWrite(struct smb_fid *fidp, struct smb_vc *vcp, + struct smb_packet *inp, struct smb_packet *outp); -extern afs_int32 smb_IoctlV3Write(struct smb_fid *fidp, struct smb_vc *vcp, struct smb_packet *inp, struct smb_packet *outp); +extern afs_int32 +smb_IoctlV3Write(struct smb_fid *fidp, struct smb_vc *vcp, + struct smb_packet *inp, struct smb_packet *outp); -extern afs_int32 smb_IoctlV3Read(struct smb_fid *fidp, struct smb_vc *vcp, struct smb_packet *inp, struct smb_packet *outp); +extern afs_int32 +smb_IoctlV3Read(struct smb_fid *fidp, struct smb_vc *vcp, + struct smb_packet *inp, struct smb_packet *outp); -extern afs_int32 smb_IoctlReadRaw(struct smb_fid *fidp, struct smb_vc *vcp, struct smb_packet *inp, - struct smb_packet *outp); +extern afs_int32 +smb_IoctlReadRaw(struct smb_fid *fidp, struct smb_vc *vcp, + struct smb_packet *inp, struct smb_packet *outp); -extern long smb_IoctlPrepareRead(struct smb_fid *fidp, smb_ioctl_t *ioctlp, cm_user_t *userp); +extern afs_int32 +smb_IoctlPrepareRead(struct smb_fid *fidp, smb_ioctl_t *ioctlp, cm_user_t *userp); extern afs_int32 -smb_ParseIoctlPath(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp, cm_scache_t **scpp, afs_uint32 flags); +smb_ParseIoctlPath(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp, + cm_scache_t **scpp, afs_uint32 flags); extern afs_int32 -smb_ParseIoctlParent(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp, cm_scache_t **scpp, char *leafp); +smb_ParseIoctlParent(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp, + cm_scache_t **scpp, clientchar_t *leafp); extern afs_int32 smb_IoctlSetToken(struct smb_ioctl *ioctlp, struct cm_user *userp); -- 1.9.4