Microsoft Visual Studio .NET 2003
available via a MSDN subscription
- Microsoft Visual Studio .NET 2005 (required for AMD64 builds)
+ Microsoft Visual Studio .NET 2005
available via a MSDN subscription
(recommended - required for 64-bit builds)
+ Microsoft Visual Studio 2008 is not supported
+
The following Microsoft SDK is required:
Microsoft Platform SDK for Windows XP SP2 or Server 2003 SP1 or Vista
http://www.microsoft.com/downloads/details.aspx?familyid=00535334-c8a6-452f-9aa0-d597d16580cc&displaylang=en
+The Microsoft Internationalized Domain Names (IDN) Mitigation APIs 1.1 is required:
+
+ http://www.microsoft.com/downloads/details.aspx?FamilyId=AD6158D7-DDBA-416A-9109-07607425A815&displaylang=en
+
The NSIS installer requires about 14 MB of storage. The following
version is supported:
npapi.h (Windows 2000,XP,2003 builds)
netcfgx.h (NSIS Loopback Adapter installer - Windows 2000,XP,2003 builds)
netcfgn.h (NSIS Loopback Adapter installer - Windows 2000,XP,2003 builds)
+ normalization.h (AFS Cache Manager)
These files come from the following Microsoft DDKs/SDKs:
Windows XP/2003 DDK - inc/wxp/
+ normalization.h:
+ Microsoft IDN Mitigation APIs 1.1 - include/
+
STEP D. Configure NTBUILD.BAT.
The NTBUILD.BAT file copied to the OpenAFS base directory must be
# License. For details, see the LICENSE file in the top-level source
# directory or online at http://www.openafs.org/dl/license10.html
-AFSDEV_AUXCDEFINES = $(AFSDEV_AUXCDEFINES) /D"_AFXDLL" -I..\kfw\inc\loadfuncs -I..\kfw\inc\krb5 -I..\kfw\inc\leash
+AFSDEV_AUXCDEFINES = $(AFSDEV_AUXCDEFINES) /D"_AFXDLL" /DSMB_UNICODE -I..\kfw\inc\loadfuncs -I..\kfw\inc\krb5 -I..\kfw\inc\leash
AFSDEV_NETGUI = 1
RELDIR=WINNT\afsd
!INCLUDE ..\..\config\NTMakefile.$(SYS_NAME)
}
#endif /* AFS_FREELANCE_CLIENT */
+ dummyLen = sizeof(smb_UseUnicode);
+ code = RegQueryValueEx(parmKey, "NegotiateUnicode", NULL, NULL,
+ (BYTE *) &smb_UseUnicode, &dummyLen);
+ if (code != ERROR_SUCCESS) {
+ smb_UseUnicode = 1; /* default on */
+ }
+ afsi_log("SMB Server Unicode Support is %s",
+ smb_UseUnicode ? "enabled" : "disabled");
+
dummyLen = sizeof(smb_hideDotFiles);
code = RegQueryValueEx(parmKey, "HideDotFiles", NULL, NULL,
(BYTE *) &smb_hideDotFiles, &dummyLen);
cm_InitCallback();
+ cm_InitNormalization();
+
code = cm_InitMappedMemory(virtualCache, cm_CachePath, stats, volumes, cells, cm_chunkSize, cacheBlocks, blockSize);
afsi_log("cm_InitMappedMemory code %x", code);
if (code != 0) {
void afsd_SetUnhandledExceptionFilter()
{
+#ifndef NOTRACE
SetUnhandledExceptionFilter(afsd_ExceptionFilter);
+#endif
}
#ifdef _DEBUG
#define PIOCTL_LOGON 0x1
#define MAX_PATH 260
+static const char utf8_prefix[] = UTF8_PREFIX;
+static const int utf8_prefix_size = sizeof(utf8_prefix) - sizeof(char);
+
osi_mutex_t cm_Afsdsbmt_Lock;
extern afs_int32 cryptall;
char * relativePath;
char * lastComponent = NULL;
afs_uint32 follow = (flags & CM_PARSE_FLAG_LITERAL ? CM_FLAG_NOMOUNTCHASE : CM_FLAG_FOLLOW);
+ int free_path = FALSE;
relativePath = ioctlp->inDatap;
/* setup the next data value for the caller to use */
* file system API. Therefore, they are not OEM characters but
* whatever the display character set is.
*/
+
// TranslateExtendedChars(relativePath);
/* This is usually nothing, but for StatMountPoint it is the file name. */
// TranslateExtendedChars(ioctlp->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
+ strings), we assume that the provided path is UTF-8. Otherwise
+ 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;
+
+ /* String is UTF-8 */
+ relativePath += utf8_prefix_size;
+ ioctlp->flags |= SMB_IOCTLFLAG_USEUTF8;
+
+ len = (ioctlp->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;
+ } else {
+ /* Not a UTF-8 string */
+ /* TODO: If this is an OEM string, we should convert it to
+ UTF-8. */
+ }
+
if (relativePath[0] == relativePath[1] &&
relativePath[1] == '\\' &&
!_strnicmp(cm_NetbiosName,relativePath+2,strlen(cm_NetbiosName)))
free(sharePath);
if (code) {
osi_Log1(afsd_logp,"cm_ParseIoctlPath [1] code 0x%x", code);
+ if (free_path)
+ free(relativePath);
return code;
}
cm_ReleaseSCache(substRootp);
if (code) {
osi_Log1(afsd_logp,"cm_ParseIoctlPath [2] code 0x%x", code);
+ if (free_path)
+ free(relativePath);
return code;
}
} else {
userp, shareName, reqp, &substRootp);
if (code) {
osi_Log1(afsd_logp,"cm_ParseIoctlPath [3] code 0x%x", code);
+ if (free_path)
+ free(relativePath);
return code;
}
if (code) {
cm_ReleaseSCache(substRootp);
osi_Log1(afsd_logp,"cm_ParseIoctlPath code [4] 0x%x", code);
+ if (free_path)
+ free(relativePath);
return code;
}
}
userp, ioctlp->tidPathp, reqp, &substRootp);
if (code) {
osi_Log1(afsd_logp,"cm_ParseIoctlPath [6] code 0x%x", code);
+ if (free_path)
+ free(relativePath);
return code;
}
if (code) {
cm_ReleaseSCache(substRootp);
osi_Log1(afsd_logp,"cm_ParseIoctlPath [7] code 0x%x", code);
+ if (free_path)
+ free(relativePath);
return code;
}
}
/* and return success */
osi_Log1(afsd_logp,"cm_ParseIoctlPath [8] code 0x%x", code);
+
+ if (free_path)
+ free(relativePath);
return 0;
}
char tbuffer[1024];
char *tp, *jp;
cm_scache_t *substRootp = NULL;
+ char *inpathp;
+ int free_path = FALSE;
+
+ inpathp = ioctlp->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
+ strings), we assume that the provided path is UTF-8. Otherwise
+ we have to convert the string to UTF-8, since that is what we
+ want to use everywhere else.*/
- StringCbCopyA(tbuffer, sizeof(tbuffer), ioctlp->inDatap);
+ if (memcmp(inpathp, utf8_prefix, utf8_prefix_size) == 0) {
+ int len, normalized_len;
+ char * normalized_path;
+
+ /* String is UTF-8 */
+ inpathp += utf8_prefix_size;
+ ioctlp->flags |= SMB_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;
+ } else {
+ /* Not a UTF-8 string */
+ /* TODO: If this is an OEM string, we should convert it to
+ UTF-8. */
+ }
+
+ StringCbCopyA(tbuffer, sizeof(tbuffer), inpathp);
tp = strrchr(tbuffer, '\\');
jp = strrchr(tbuffer, '/');
if (!tp)
if (!tp) {
StringCbCopyA(tbuffer, sizeof(tbuffer), "\\");
if (leafp)
- StringCbCopyA(leafp, LEAF_SIZE, ioctlp->inDatap);
+ StringCbCopyA(leafp, LEAF_SIZE, inpathp);
}
else {
*tp = 0;
StringCbCopyA(leafp, LEAF_SIZE, tp+1);
}
+ if (free_path)
+ 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_cell_t *cellp;
cm_req_t req;
struct rx_connection * callp;
+ int len;
cm_InitReq(&req);
cp = ioctlp->inDatap;
memcpy((char *)&volStat, cp, sizeof(AFSFetchVolumeStatus));
cp += sizeof(AFSFetchVolumeStatus);
- StringCbCopyA(volName, sizeof(volName), cp);
- cp += strlen(volName)+1;
- StringCbCopyA(offLineMsg, sizeof(offLineMsg), cp);
- cp += strlen(offLineMsg)+1;
- StringCbCopyA(motd, sizeof(motd), cp);
+
+ len = strlen(cp) + 1;
+ cm_NormalizeUtf8String(cp, len, volName, sizeof(volName));
+ cp += len;
+
+ len = strlen(cp) + 1;
+ cm_NormalizeUtf8String(cp, len, offLineMsg, sizeof(offLineMsg));
+ cp += len;
+
+ len = strlen(cp) + 1;
+ cm_NormalizeUtf8String(cp, len, motd, sizeof(motd));
storeStat.Mask = 0;
if (volStat.MinQuota != -1) {
storeStat.MinQuota = volStat.MinQuota;
return code;
/* Translate chars for the mount point name */
+ if (!(ioctlp->flags & SMB_IOCTLFLAG_USEUTF8)) {
TranslateExtendedChars(leaf);
+ }
/*
* The fs command allows the user to specify partial cell names on NT. These must
cm_attr_t tattr;
char *cp;
cm_req_t req;
+ char *symlp;
+ int free_syml = FALSE;
cm_InitReq(&req);
code = cm_ParseIoctlParent(ioctlp, userp, &req, &dscp, leaf);
if (code) return code;
+ if (!(ioctlp->flags & SMB_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 */
- cp = 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;
#ifdef AFS_FREELANCE_CLIENT
if (cm_freelanceEnabled && dscp == cm_data.rootSCachep) {
cm_ReleaseSCache(dscp);
+ if (free_syml)
+ free(symlp);
+
return code;
}
return 0;
}
+long cm_IoctlUnicodeControl(struct smb_ioctl *ioctlp, struct cm_user * userp)
+{
+ long result = 0;
+#ifdef SMB_UNICODE
+ long cmd;
+
+ cm_SkipIoctlPath(ioctlp);
+
+ memcpy(&cmd, ioctlp->inDatap, sizeof(long));
+
+ if (cmd & 2) {
+ /* Setting the Unicode flag */
+ LONG newflag;
+
+ newflag = ((cmd & 1) == 1);
+
+ InterlockedExchange(&smb_UseUnicode, newflag);
+ }
+
+ result = smb_UseUnicode;
+#else
+ result = 2;
+#endif
+
+ memcpy(ioctlp->outDatap, &result, sizeof(result));
+ ioctlp->outDatap += sizeof(result);
+
+ return 0;
+}
+
long cm_IoctlUUIDControl(struct smb_ioctl * ioctlp, struct cm_user *userp)
{
long cmd;
afsUUID uuid;
+ cm_SkipIoctlPath(ioctlp);
+
memcpy(&cmd, ioctlp->inDatap, sizeof(long));
if (cmd) { /* generate a new UUID */
return 0;
}
+
+
/*
* functions to dump contents of various structures.
* In debug build (linked with crt debug library) will dump allocated but not freed memory
struct VolStatTest * testp;
cm_req_t req;
afs_uint32 n;
- size_t len;
cm_InitReq(&req);
extern unsigned int cm_sysNameCount;
extern char * 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.
+ The sequence ESC '%' 'G' is used by ISO-2022 to designate UTF-8
+ strings. */
+#define UTF8_PREFIX "\33%G"
+
/* flags for rxstats pioctl */
#define AFSCALL_RXSTATS_MASK 0x7 /* Valid flag bits */
extern long cm_IoctlVolStatTest(struct smb_ioctl *ioctlp, struct cm_user *userp);
+extern long cm_IoctlUnicodeControl(struct smb_ioctl *ioctlp, struct cm_user * userp);
+
#endif /* __CM_IOCTL_INTERFACES_ONLY__ */
#endif /* __CM_IOCTL_H_ENV__ */
#include <osi.h>
#include <rx/rx.h>
+#define STRSAFE_NO_DEPRECATE
+#include <strsafe.h>
+
static osi_once_t cm_utilsOnce;
cm_spaceListp = tsp;
lock_ReleaseWrite(&cm_utilsLock);
}
+
+/* This is part of the Microsoft Internationalized Domain Name
+ Mitigation APIs. */
+#include <normalization.h>
+
+int
+(WINAPI *pNormalizeString)( __in NORM_FORM NormForm,
+ __in_ecount(cwSrcLength) LPCWSTR lpSrcString,
+ __in int cwSrcLength,
+ __out_ecount(cwDstLength) LPWSTR lpDstString,
+ __in int cwDstLength ) = NULL;
+
+BOOL
+(WINAPI *pIsNormalizedString)( __in NORM_FORM NormForm,
+ __in_ecount(cwLength) LPCWSTR lpString,
+ __in int cwLength ) = NULL;
+
+
+#define NLSDLLNAME "Normaliz.dll"
+#define NLSMAXCCH 1024
+#define NLSERRCCH 8
+
+#define AFS_NORM_FORM NormalizationC
+
+long cm_InitNormalization(void)
+{
+ HMODULE h_Nls;
+
+ if (pNormalizeString != NULL)
+ return 0;
+
+ h_Nls = LoadLibrary(NLSDLLNAME);
+ if (h_Nls == INVALID_HANDLE_VALUE) {
+ afsi_log("Can't load " NLSDLLNAME ": LastError=%d", GetLastError());
+ return 1;
+ }
+
+ pNormalizeString = GetProcAddress(h_Nls, "NormalizeString");
+ pIsNormalizedString = GetProcAddress(h_Nls, "IsNormalizedString");
+
+ return (pNormalizeString && pIsNormalizedString);
+}
+
+/* \brief Normalize a UTF-16 string.
+
+ If the supplied destination buffer is
+ insufficient or NULL, then a new buffer will be allocated to hold
+ the normalized string.
+
+ \param[in] src : Source UTF-16 string. Length is specified in
+ cch_src.
+
+ \param[in] cch_src : The character count in cch_src is assumed to
+ be tight and include the terminating NULL character if there is
+ one. If the NULL is absent, the resulting string will not be
+ NULL terminated.
+
+ \param[out] ext_dest : The destination buffer. Can be NULL, in
+ which case *pcch_dest MUST be NULL.
+
+ \param[in,out] pcch_dest : On entry *pcch_dest contains a count of
+ characters in the destination buffer. On exit, it will contain
+ a count of characters that were copied to the destination
+ buffer.
+
+ Returns a pointer to the buffer containing the normalized string or
+ NULL if the call was unsuccessful. If the returned destination
+ buffer is different fron the supplied buffer and non-NULL, it
+ should be freed using free().
+*/
+static wchar_t *
+NormalizeUtf16String(const wchar_t * src, int cch_src, wchar_t * ext_dest, int *pcch_dest)
+{
+ if ((pIsNormalizedString && (*pIsNormalizedString)(AFS_NORM_FORM, src, cch_src)) ||
+ (!pNormalizeString)) {
+
+ int rv;
+ DWORD gle;
+ int tries = 10;
+ wchar_t * dest;
+ int cch_dest = *pcch_dest;
+
+ dest = ext_dest;
+
+ while (tries-- > 0) {
+
+ rv = (*pNormalizeString)(AFS_NORM_FORM, src, cch_src, dest, cch_dest);
+
+ if (rv <= 0 && (gle = GetLastError()) != ERROR_SUCCESS) {
+#ifdef DEBUG
+ osi_Log1(afsd_logp, "NormalizeUtf16String error = %d", gle);
+#endif
+ if (gle == ERROR_INSUFFICIENT_BUFFER) {
+
+ /* The buffer wasn't big enough. We are going to
+ try allocating one. */
+
+ cch_dest = (-rv) + NLSERRCCH;
+ goto cont;
+
+ } else {
+ /* Something else is wrong */
+ break;
+ }
+
+ } else if (rv < 0) { /* rv < 0 && gle == ERROR_SUCCESS */
+
+ /* Technically not one of the expected outcomes */
+ break;
+
+ } else { /* rv > 0 || (rv == 0 && gle == ERROR_SUCCESS) */
+
+ /* Possibly succeeded */
+
+ if (rv == 0) { /* Succeeded and the return string is empty */
+ *pcch_dest = 0;
+ return dest;
+ }
+
+ if (cch_dest == 0) {
+ /* Nope. We only calculated the required size of the buffer */
+
+ cch_dest = rv + NLSERRCCH;
+ goto cont;
+ }
+
+ *pcch_dest = rv;
+
+ /* Success! */
+ return dest;
+ }
+
+ cont:
+ if (dest != ext_dest && dest)
+ free(dest);
+ dest = malloc(cch_dest * sizeof(wchar_t));
+ }
+
+ /* Failed */
+
+ if (dest != ext_dest && dest)
+ free(dest);
+
+ *pcch_dest = 0;
+ return NULL;
+ } else {
+
+ /* No need to or unable to normalize. Just copy the string */
+ if (SUCCEEDED(StringCchCopyNW(ext_dest, *pcch_dest, src, cch_src))) {
+ *pcch_dest = cch_src;
+ return ext_dest;
+ } else {
+ *pcch_dest = 0;
+ return NULL;
+ }
+ }
+}
+
+/* \brief Normalize a UTF-16 string into a UTF-8 string.
+
+ \param[in] src : Source string.
+
+ \param[in] cch_src : Count of characters in src. If the count includes the
+ NULL terminator, then the resulting string will be NULL
+ terminated. If it is -1, then src is assumed to be NULL
+ terminated.
+
+ \param[out] adest : Destination buffer.
+
+ \param[in] cch_adest : Number of characters in the destination buffer.
+
+ Returns the number of characters stored into cch_adest. This will
+ include the terminating NULL if cch_src included the terminating
+ NULL or was -1. If this is 0, then the operation was unsuccessful.
+ */
+long cm_NormalizeUtf16StringToUtf8(const wchar_t * src, int cch_src,
+ char * adest, int cch_adest)
+{
+ if (cch_src < 0) {
+ size_t cch;
+
+ if (FAILED(StringCchLengthW(src, NLSMAXCCH, &cch)))
+ return CM_ERROR_TOOBIG;
+
+ cch_src = cch+1;
+ }
+
+ {
+ wchar_t nbuf[NLSMAXCCH];
+ wchar_t * normalized;
+ int cch_norm = NLSMAXCCH;
+
+ normalized = NormalizeUtf16String(src, cch_src, nbuf, &cch_norm);
+ if (normalized) {
+ cch_adest = WideCharToMultiByte(CP_UTF8, 0, normalized, cch_norm,
+ adest, cch_adest, NULL, 0);
+
+ if (normalized != nbuf && normalized)
+ free(normalized);
+
+ return cch_adest;
+
+ } else {
+
+ return 0;
+
+ }
+ }
+}
+
+
+/* \brief Normalize a UTF-8 string.
+
+ \param[in] src String to normalize.
+
+ \param[in] cch_src : Count of characters in src. If this value is
+ -1, then src is assumed to be NULL terminated. The translated
+ string will be NULL terminated only if this is -1 or the count
+ includes the terminating NULL.
+
+ \param[out] adest : Destination string.
+
+ \param[in] cch_adest : Number of characters in the destination
+ string.
+
+ Returns the number of characters stored into adest or 0 if the call
+ was unsuccessful.
+ */
+long cm_NormalizeUtf8String(const char * src, int cch_src,
+ char * adest, int cch_adest)
+{
+ 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') {
+ *adest = '\0';
+ return 1;
+ }
+
+ cch = MultiByteToWideChar(CP_UTF8, 0, src, cch_src * sizeof(char),
+ wsrcbuf, NLSMAXCCH);
+
+ if (cch == 0) {
+#ifdef DEBUG
+ DebugBreak();
+#endif
+ return 0;
+ }
+
+ cch_norm = 0;
+ wnorm = NormalizeUtf16String(wsrcbuf, cch, NULL, &cch_norm);
+ if (wnorm == NULL) {
+#ifdef DEBUG
+ DebugBreak();
+#endif
+ return 0;
+ }
+
+ cch = WideCharToMultiByte(CP_UTF8, 0, wnorm, cch_norm,
+ adest, cch_adest * sizeof(char),
+ NULL, FALSE);
+
+ if (wnorm)
+ free(wnorm);
+
+ return cch;
+}
extern long cm_MapRPCErrorRmdir(long error, cm_req_t *reqp);
extern long cm_MapVLRPCError(long error, cm_req_t *reqp);
+extern long cm_InitNormalization(void);
+extern long cm_NormalizeUtf16StringToUtf8(const wchar_t * src, int cch_src,
+ char * adest, int cch_adest);
+extern long cm_NormalizeUtf8String(const char * src, int cch_src,
+ char * adest, int cch_adest);
#endif /* __CM_UTILS_H_ENV__ */
blob.out_size = MAXSIZE;
blob.out = space;
- code = pioctl(apath, VIOC_FILE_CELL_NAME, &blob, 1);
+ code = pioctl_utf8(apath, VIOC_FILE_CELL_NAME, &blob, 1);
if (code) {
if ((errno == EINVAL) || (errno == ENOENT))
return 0;
blob.out_size = MAXSIZE;
blob.out = space;
- code = pioctl(apath, VIOC_FILE_CELL_NAME, &blob, 1);
+ code = pioctl_utf8(apath, VIOC_FILE_CELL_NAME, &blob, 1);
if (code == 0)
return !stricmp("Freelance.Local.Root",space);
return 1; /* assume it is because it is more restrictive that way */
}
ta->minuslist = first;
- exit:
return ta;
nminus_err:
blob.out_size = MAXSIZE;
blob.in_size = idf;
blob.in = blob.out = space;
- code = pioctl(ti->data, VIOCGETAL, &blob, 1);
+ code = pioctl_utf8(ti->data, VIOCGETAL, &blob, 1);
if (code) {
Die(errno, ti->data);
error = 1;
blob.in = AclToString(ta);
blob.out_size=0;
blob.in_size = 1+(long)strlen(blob.in);
- code = pioctl(ti->data, VIOCSETAL, &blob, 1);
+ code = pioctl_utf8(ti->data, VIOCSETAL, &blob, 1);
if (code) {
if (errno == EINVAL) {
if (ta->dfs) {
blob.out_size = MAXSIZE;
blob.in_size = idf;
blob.in = blob.out = space;
- code = pioctl(as->parms[0].items->data, VIOCGETAL, &blob, 1);
+ code = pioctl_utf8(as->parms[0].items->data, VIOCGETAL, &blob, 1);
if (code) {
Die(errno, as->parms[0].items->data);
return 1;
blob.out_size = MAXSIZE;
blob.in_size = idf;
blob.in = blob.out = space;
- code = pioctl(ti->data, VIOCGETAL, &blob, 1);
+ code = pioctl_utf8(ti->data, VIOCGETAL, &blob, 1);
if (code) {
Die(errno, ti->data);
error = 1;
blob.in = AclToString(ta);
blob.out_size=0;
blob.in_size = 1+(long)strlen(blob.in);
- code = pioctl(ti->data, VIOCSETAL, &blob, 1);
+ code = pioctl_utf8(ti->data, VIOCSETAL, &blob, 1);
if (code) {
if (errno == EINVAL) {
fprintf(stderr,
return error;
}
-/* pioctl() call to get the cellname of a pathname */
+/* pioctl_utf8() call to get the cellname of a pathname */
static afs_int32
GetCell(char *fname, char *cellname)
{
blob.out_size = MAXCELLCHARS;
blob.out = cellname;
- code = pioctl(fname, VIOC_FILE_CELL_NAME, &blob, 1);
+ code = pioctl_utf8(fname, VIOC_FILE_CELL_NAME, &blob, 1);
return code;
}
blob.out_size = MAXSIZE;
blob.in_size = 0;
blob.out = space;
- code = pioctl(ti->data, VIOCGETAL, &blob, 1);
+ code = pioctl_utf8(ti->data, VIOCGETAL, &blob, 1);
if (code) {
Die(errno, ti->data);
error = 1;
blob.in=AclToString(ta);
blob.in_size = (long)strlen(blob.in)+1;
blob.out_size = 0;
- code = pioctl(ti->data, VIOCSETAL, &blob, 1);
+ code = pioctl_utf8(ti->data, VIOCSETAL, &blob, 1);
if (code) {
if (errno == EINVAL) {
fprintf(stderr,
blob.out_size = MAXSIZE;
blob.in_size = idf;
blob.in = blob.out = space;
- code = pioctl(ti->data, VIOCGETAL, &blob, 1);
+ code = pioctl_utf8(ti->data, VIOCGETAL, &blob, 1);
if (code) {
Die(errno, ti->data);
error = 1;
struct ViceIoctl blob;
blob.in_size = blob.out_size = 0;
- code = pioctl(NULL, VIOC_FLUSHALL, &blob, 0);
+ code = pioctl_utf8(NULL, VIOC_FLUSHALL, &blob, 0);
if (code) {
fprintf(stderr, "Error flushing all ");
return 1;
SetDotDefault(&as->parms[0].items);
for(ti=as->parms[0].items; ti; ti=ti->next) {
blob.in_size = blob.out_size = 0;
- code = pioctl(ti->data, VIOC_FLUSHVOLUME, &blob, 0);
+ code = pioctl_utf8(ti->data, VIOC_FLUSHVOLUME, &blob, 0);
if (code) {
fprintf(stderr, "Error flushing volume ");
perror(ti->data);
blob.in = &options;
blob.out_size = 0;
- code = pioctl(ti->data, VIOCFLUSH, &blob, 0);
+ code = pioctl_utf8(ti->data, VIOCFLUSH, &blob, 0);
if (code) {
if (errno == EMFILE) {
fprintf(stderr, "%s: Can't flush active file %s\n", pn,
input += strlen(motd) + 1;
} else
*(input++) = '\0';
- code = pioctl(ti->data,VIOCSETVOLSTAT, &blob, 1);
+ code = pioctl_utf8(ti->data,VIOCSETVOLSTAT, &blob, 1);
if (code) {
Die(errno, ti->data);
error = 1;
blob.out_size = sizeof(cm_fid_t);
blob.out = (char *) &fid;
- if (0 == pioctl(ti->data, VIOCGETFID, &blob, 1)) {
+ if (0 == pioctl_utf8(ti->data, VIOCGETFID, &blob, 1)) {
options.field_flags |= CM_IOCTL_QOPTS_FIELD_FID;
options.fid = fid;
} else {
blob.out_size = sizeof(filetype);
blob.out = &filetype;
- code = pioctl(ti->data, VIOC_GETFILETYPE, &blob, 1);
+ code = pioctl_utf8(ti->data, VIOC_GETFILETYPE, &blob, 1);
blob.out_size = MAXCELLCHARS;
blob.out = cell;
- code = pioctl(ti->data, VIOC_FILE_CELL_NAME, &blob, 1);
+ code = pioctl_utf8(ti->data, VIOC_FILE_CELL_NAME, &blob, 1);
printf("%s %s (%u.%u.%u) contained in cell %s\n",
filetypestr(filetype),
ti->data, fid.volume, fid.vnode, fid.unique,
blob.out_size = 2 * sizeof(afs_uint32);
blob.out = (char *) &owner;
- if (0 == pioctl(ti->data, VIOCGETOWNER, &blob, 1)) {
+ if (0 == pioctl_utf8(ti->data, VIOCGETOWNER, &blob, 1)) {
char oname[PR_MAXNAMELEN] = "(unknown)";
char confDir[257];
blob.out = space;
blob.out_size = MAXSIZE;
- code = pioctl(ti->data, VIOCGETVOLSTAT, &blob, 1);
+ code = pioctl_utf8(ti->data, VIOCGETVOLSTAT, &blob, 1);
if (code == 0) {
status = (VolumeStatus *)space;
name = (char *)status + sizeof(*status);
}
errno = 0;
- code = pioctl(ti->data, VIOC_PATH_AVAILABILITY, &blob, 1);
+ code = pioctl_utf8(ti->data, VIOC_PATH_AVAILABILITY, &blob, 1);
switch (errno) {
case 0:
printf("Volume is online\n");
blob.out_size = MAXSIZE;
blob.in_size = 0;
blob.out = space;
- code = pioctl(ti->data, VIOCGETVOLSTAT, &blob, 1);
+ code = pioctl_utf8(ti->data, VIOCGETVOLSTAT, &blob, 1);
if (code) {
Die(errno, ti->data);
error = 1;
blob.out_size = sizeof(cm_fid_t);
blob.out = (char *) &fid;
- if (0 == pioctl(ti->data, VIOCGETFID, &blob, 1)) {
+ if (0 == pioctl_utf8(ti->data, VIOCGETFID, &blob, 1)) {
options.field_flags |= CM_IOCTL_QOPTS_FIELD_FID;
options.fid = fid;
} else {
blob.out_size = sizeof(filetype);
blob.out = &filetype;
- code = pioctl(ti->data, VIOC_GETFILETYPE, &blob, 1);
+ code = pioctl_utf8(ti->data, VIOC_GETFILETYPE, &blob, 1);
blob.out_size = MAXSIZE;
blob.out = space;
memset(space, 0, sizeof(space));
- code = pioctl(ti->data, VIOCWHEREIS, &blob, 1);
+ code = pioctl_utf8(ti->data, VIOCWHEREIS, &blob, 1);
if (code) {
Die(errno, ti->data);
error = 1;
blob.out_size = MAXSIZE;
blob.in_size = 0;
blob.out = space;
- code = pioctl(ti->data, VIOCGETVOLSTAT, &blob, 1);
+ code = pioctl_utf8(ti->data, VIOCGETVOLSTAT, &blob, 1);
if (code) {
Die(errno, ti->data);
error = 1;
blob.out_size = MAXSIZE;
blob.in_size = 0;
blob.out = space;
- code = pioctl(ti->data, VIOCGETVOLSTAT, &blob, 1);
+ code = pioctl_utf8(ti->data, VIOCGETVOLSTAT, &blob, 1);
if (code) {
Die(errno, ti->data);
error = 1;
blob.out = space;
memset(space, 0, MAXSIZE);
- code = pioctl(parent_dir, VIOC_AFS_STAT_MT_PT, &blob, 1);
+ code = pioctl_utf8(parent_dir, VIOC_AFS_STAT_MT_PT, &blob, 1);
if (code == 0) {
printf("'%s' is a %smount point for volume '%s'\n",
blob.in_size = 0;
blob.out_size = sizeof(localCellName);
blob.out = localCellName;
- code = pioctl(parent, VIOC_GET_WS_CELL, &blob, 1);
+ code = pioctl_utf8(parent, VIOC_GET_WS_CELL, &blob, 1);
if (!code)
cellName = localCellName;
}
blob.in_size = 1 + (long)strlen(space);
blob.in = space;
blob.out = NULL;
- code = pioctl(path, VIOC_AFS_CREATE_MT_PT, &blob, 0);
+ code = pioctl_utf8(path, VIOC_AFS_CREATE_MT_PT, &blob, 0);
#else /* not WIN32 */
code = symlink(space, path);
#endif /* not WIN32 */
blob.in_size = (long)strlen(tp)+1;
blob.out = lsbuffer;
blob.out_size = sizeof(lsbuffer);
- code = pioctl(tbuffer, VIOC_AFS_STAT_MT_PT, &blob, 0);
+ code = pioctl_utf8(tbuffer, VIOC_AFS_STAT_MT_PT, &blob, 0);
if (code) {
if (errno == EINVAL) {
fprintf(stderr,"%s: '%s' is not a mount point.\n", pn, ti->data);
blob.out_size = 0;
blob.in = tp;
blob.in_size = (long)strlen(tp)+1;
- code = pioctl(tbuffer, VIOC_AFS_DELETE_MT_PT, &blob, 0);
+ code = pioctl_utf8(tbuffer, VIOC_AFS_DELETE_MT_PT, &blob, 0);
if (code) {
Die(errno, ti->data);
error = 1;
#endif /* WIN32 */
}
- code = pioctl(0, VIOCCKSERV, &blob, 1);
+ code = pioctl_utf8(0, VIOCCKSERV, &blob, 1);
if (code) {
if ((errno == EACCES) && (checkserv.tinterval > 0)) {
printf("Must be root to change -interval\n");
if (code)
return 1;
- code = pioctl(0, VIOC_GAG, &blob, 1);
+ code = pioctl_utf8(0, VIOC_GAG, &blob, 1);
if (code) {
Die(errno, 0);
return 1;
blob.in_size = 0;
blob.out_size = 0;
- code = pioctl(0, VIOCCKBACK, &blob, 1);
+ code = pioctl_utf8(0, VIOCCKBACK, &blob, 1);
if (code) {
Die(errno, 0);
return 1;
blob.in = (char *) &temp;
blob.in_size = sizeof(afs_int32);
blob.out_size = 0;
- code = pioctl(0, VIOCSETCACHESIZE, &blob, 1);
+ code = pioctl_utf8(0, VIOCSETCACHESIZE, &blob, 1);
if (code) {
Die(errno, (char *) 0);
return 1;
blob.in_size = 0;
blob.out_size = sizeof(parms);
blob.out = (char *) &parms;
- code = pioctl(0, VIOCGETCACHEPARMS, &blob, 1);
+ code = pioctl_utf8(0, VIOCGETCACHEPARMS, &blob, 1);
if (code) {
Die(errno, NULL);
return 1;
blob.in_size = sizeof(afs_int32);
blob.in = space;
blob.out = space;
- code = pioctl(0, VIOCGETCELL, &blob, 1);
+ code = pioctl_utf8(0, VIOCGETCELL, &blob, 1);
if (code < 0) {
if (errno == EDOM)
break; /* done with the list */
blob.in_size = sizeof(afs_int32);
blob.in = space;
blob.out = space;
- code = pioctl(0, VIOC_GETALIAS, &blob, 1);
+ code = pioctl_utf8(0, VIOC_GETALIAS, &blob, 1);
if (code < 0) {
if (errno == EDOM)
break; /* done with the list */
blob.in = (char *) &hostAddr;
blob.out = (char *) &hostAddr;
- code = pioctl(0, VIOC_CBADDR, &blob, 1);
+ code = pioctl_utf8(0, VIOC_CBADDR, &blob, 1);
if (code < 0) {
Die(errno, 0);
return 1;
blob.in_size = size;
blob.in = space;
blob.out_size = 0;
- code = pioctl(0, VIOCNEWCELL, &blob, 1);
+ code = pioctl_utf8(0, VIOCNEWCELL, &blob, 1);
if (code < 0)
Die(errno, 0);
return 0;
blob.out_size = MAXSIZE;
blob.out = space;
- code = pioctl((char *) 0, VIOCNEWCELL, &blob, 1);
+ code = pioctl_utf8((char *) 0, VIOCNEWCELL, &blob, 1);
if (code) {
Die(errno, (char *) 0);
blob.in = space;
blob.out_size = 0;
blob.out = space;
- code = pioctl(0, VIOC_NEWALIAS, &blob, 1);
+ code = pioctl_utf8(0, VIOC_NEWALIAS, &blob, 1);
if (code < 0) {
if (errno == EEXIST) {
fprintf(stderr,
blob.out_size = sizeof(cm_fid_t);
blob.out = (char *) &fid;
- if (0 == pioctl(ti->data, VIOCGETFID, &blob, 1)) {
+ if (0 == pioctl_utf8(ti->data, VIOCGETFID, &blob, 1)) {
options.field_flags |= CM_IOCTL_QOPTS_FIELD_FID;
options.fid = fid;
} else {
blob.out_size = sizeof(filetype);
blob.out = &filetype;
- code = pioctl(ti->data, VIOC_GETFILETYPE, &blob, 1);
+ code = pioctl_utf8(ti->data, VIOC_GETFILETYPE, &blob, 1);
blob.out_size = MAXCELLCHARS;
blob.out = cell;
- code = pioctl(ti->data, VIOC_FILE_CELL_NAME, &blob, 1);
+ code = pioctl_utf8(ti->data, VIOC_FILE_CELL_NAME, &blob, 1);
if (code) {
if (errno == ENOENT)
fprintf(stderr,"%s: no such cell as '%s'\n", pn, ti->data);
blob.out_size = MAXSIZE;
blob.out = space;
- code = pioctl(NULL, VIOC_GET_WS_CELL, &blob, 1);
+ code = pioctl_utf8(NULL, VIOC_GET_WS_CELL, &blob, 1);
if (code) {
Die(errno, NULL);
blob.out_size = sizeof(afs_int32);
blob.in = (char *) &hostAddr;
blob.out = (char *) &hostAddr;
- code = pioctl(0, VIOC_AFS_MARINER_HOST, &blob, 1);
+ code = pioctl_utf8(0, VIOC_AFS_MARINER_HOST, &blob, 1);
if (code) {
Die(errno, 0);
return 1;
*(input++) = '\0';
}
memcpy(space, &setp, sizeof(afs_int32));
- code = pioctl(0, VIOC_AFS_SYSNAME, &blob, 1);
+ code = pioctl_utf8(0, VIOC_AFS_SYSNAME, &blob, 1);
if (code) {
Die(errno, 0);
return 1;
blob.in_size = sizeof(afs_int32);
blob.out = (char *) &exportcall;
blob.out_size = sizeof(afs_int32);
- code = pioctl(0, VIOC_EXPORTAFS, &blob, 1);
+ code = pioctl_utf8(0, VIOC_EXPORTAFS, &blob, 1);
if (code) {
if (errno == ENODEV) {
fprintf(stderr,
}
blob.in_size = 1+(long)strlen(info.name);
blob.in = info.name;
- code = pioctl(0, VIOC_GETCELLSTATUS, &blob, 1);
+ code = pioctl_utf8(0, VIOC_GETCELLSTATUS, &blob, 1);
if (code) {
if (errno == ENOENT)
fprintf(stderr,"%s: the cell named '%s' does not exist\n", pn, info.name);
blob.in = (caddr_t) &args;
blob.out_size = 0;
blob.out = (caddr_t) 0;
- code = pioctl(0, VIOC_SETCELLSTATUS, &blob, 1);
+ code = pioctl_utf8(0, VIOC_SETCELLSTATUS, &blob, 1);
if (code) {
Die(errno, info.name); /* XXX added cell name to Die() call */
error = 1;
{
int code;
cm_SSetPref_t *ssp;
- code = pioctl(0, VIOC_SETSPREFS, &gblob, 1);
+ code = pioctl_utf8(0, VIOC_SETSPREFS, &gblob, 1);
ssp = (cm_SSetPref_t *)space;
gblob.in_size = (long)(((char *)&(ssp->servers[0])) - (char *)ssp);
{
int code;
- code = pioctl(0, VIOC_SETSPREFS, &gblob, 1);
+ code = pioctl_utf8(0, VIOC_SETSPREFS, &gblob, 1);
if (code && (errno == EINVAL)) {
struct setspref *ssp;
ssp = (struct setspref *)gblob.in;
if (!(ssp->flags & DBservers)) {
gblob.in = (void *)&(ssp->servers[0]);
gblob.in_size -= ((char *)&(ssp->servers[0])) - (char *)ssp;
- code = pioctl(0, VIOC_SETSPREFS33, &gblob, 1);
+ code = pioctl_utf8(0, VIOC_SETSPREFS33, &gblob, 1);
return code ? errno : 0;
}
fprintf(stderr,
in->num_servers = (MAXSIZE - 2*sizeof(short))/sizeof(struct cm_SPref);
in->flags = vlservers;
- code = pioctl(0, VIOC_GETSPREFS, &blob, 1);
+ code = pioctl_utf8(0, VIOC_GETSPREFS, &blob, 1);
if (code){
perror("getserverprefs pioctl");
Die (errno,0);
(MAXSIZE - 2 * sizeof(short)) / sizeof(struct spref);
in->flags = vlservers;
- code = pioctl(0, VIOC_GETSPREFS, &blob, 1);
+ code = pioctl_utf8(0, VIOC_GETSPREFS, &blob, 1);
if (code) {
perror("getserverprefs pioctl");
return 1;
}
#endif /* WIN32 */
+static afs_int32
+SmbUnicodeCmd(struct cmd_syndesc * asp, void * arock)
+{
+ long inValue = 0;
+ long outValue = 0;
+ long code;
+
+ struct ViceIoctl blob;
+
+ if (asp->parms[0].items) {
+ /* On */
+
+ inValue = 3;
+ } else if (asp->parms[1].items) {
+ /* Off */
+
+ inValue = 2;
+ }
+
+ if (inValue != 0 && !IsAdmin()) {
+ fprintf (stderr, "Permission denied: Requires AFS Client Administrator access.\n");
+ return EACCES;
+ }
+
+ blob.in_size = sizeof(inValue);
+ blob.in = (char *) &inValue;
+ blob.out_size = sizeof(outValue);
+ blob.out = (char *) &outValue;
+
+ code = pioctl_utf8(NULL, VIOC_UNICODECTL, &blob, 1);
+ if (code) {
+ Die(errno, NULL);
+ return code;
+ }
+
+ if (outValue != 2) {
+ printf("Unicode support is %s%s.\n",
+ ((outValue != 0)? "enabled":"disabled"),
+ ((inValue != 0)? " for new SMB connections":""));
+ } else {
+ printf("Unicode support is absent in this installation of OpenAFS.\n");
+ }
+
+ return 0;
+}
+
static int
UuidCmd(struct cmd_syndesc *asp, void *arock)
{
blob.out_size = sizeof(outValue);
blob.out = (char *) &outValue;
- code = pioctl(NULL, VIOC_UUIDCTL, &blob, 1);
+ code = pioctl_utf8(NULL, VIOC_UUIDCTL, &blob, 1);
if (code) {
Die(errno, NULL);
return code;
blob.out_size = sizeof(long);
blob.out = (char *) &outValue;
- code = pioctl(NULL, VIOC_TRACECTL, &blob, 1);
+ code = pioctl_utf8(NULL, VIOC_TRACECTL, &blob, 1);
if (code) {
Die(errno, NULL);
return code;
/* once per -file */
for (ti = as->parms[1].items; ti; ti = ti->next) {
/* Do this solely to see if the file is there */
- code = pioctl(ti->data, VIOCWHEREIS, &blob, 1);
+ code = pioctl_utf8(ti->data, VIOCWHEREIS, &blob, 1);
if (code) {
Die(errno, ti->data);
error = 1;
continue;
}
- code = pioctl(ti->data, VIOC_STOREBEHIND, &blob, 1);
+ code = pioctl_utf8(ti->data, VIOC_STOREBEHIND, &blob, 1);
if (code) {
Die(errno, ti->data);
error = 1;
*/
if (!as->parms[1].items || (allfiles != -1)) {
tsb.sb_default = allfiles;
- code = pioctl(0, VIOC_STOREBEHIND, &blob, 1);
+ code = pioctl_utf8(0, VIOC_STOREBEHIND, &blob, 1);
if (code) {
Die(errno, ((allfiles == -1) ? 0 : "-allfiles"));
error = 1;
blob.in = (char *) &flag;
blob.in_size = sizeof(flag);
blob.out_size = 0;
- code = pioctl(0, VIOC_SETRXKCRYPT, &blob, 1);
+ code = pioctl_utf8(0, VIOC_SETRXKCRYPT, &blob, 1);
if (code)
Die(code, NULL);
return 0;
blob.out_size = sizeof(flag);
blob.out = space;
- code = pioctl(0, VIOC_GETRXKCRYPT, &blob, 1);
+ code = pioctl_utf8(0, VIOC_GETRXKCRYPT, &blob, 1);
if (code)
Die(code, NULL);
blob.out_size = sizeof(long);
blob.out = (char *) &outValue;
- code = pioctl(NULL, VIOC_TRACEMEMDUMP, &blob, 1);
+ code = pioctl_utf8(NULL, VIOC_TRACEMEMDUMP, &blob, 1);
if (code) {
Die(errno, NULL);
return code;
in->num_servers =
(MAXSIZE - 2 * sizeof(short)) / sizeof(struct spref);
/* returns addr in network byte order */
- code = pioctl(0, VIOC_GETCPREFS, &blob, 1);
+ code = pioctl_utf8(0, VIOC_GETCPREFS, &blob, 1);
if (code) {
perror("getClientInterfaceAddr pioctl");
return 1;
}
blob.in_size = sizeUsed - sizeof(struct spref);
- code = pioctl(0, VIOC_SETCPREFS, &blob, 1); /* network order */
+ code = pioctl_utf8(0, VIOC_SETCPREFS, &blob, 1); /* network order */
if (code) {
Die(errno, 0);
error = 1;
blob.out_size = 0;
memset(space, 0, MAXSIZE);
- code = pioctl(parent_dir, VIOC_AFS_FLUSHMOUNT, &blob, 1);
+ code = pioctl_utf8(parent_dir, VIOC_AFS_FLUSHMOUNT, &blob, 1);
if (code != 0) {
if (errno == EINVAL) {
blob.in_size = sizeof(afs_int32);
blob.out_size = 0;
- code = pioctl(NULL, VIOC_RXSTAT_PROC, &blob, 1);
+ code = pioctl_utf8(NULL, VIOC_RXSTAT_PROC, &blob, 1);
if (code != 0) {
Die(errno, NULL);
return 1;
blob.in_size = sizeof(afs_int32);
blob.out_size = 0;
- code = pioctl(NULL, VIOC_RXSTAT_PEER, &blob, 1);
+ code = pioctl_utf8(NULL, VIOC_RXSTAT_PEER, &blob, 1);
if (code != 0) {
Die(errno, NULL);
return 1;
blob.in_size = sizeof(test);
blob.out_size = 0;
- code = pioctl(NULL, VIOC_VOLSTAT_TEST, &blob, 1);
+ code = pioctl_utf8(NULL, VIOC_VOLSTAT_TEST, &blob, 1);
if (code != 0) {
Die(errno, NULL);
return 1;
#include "AFS_component_version_number.c"
#endif
-main(int argc, char **argv)
+static void
+FreeUtf8CmdLine(int argc, char ** argv)
+{
+ int i;
+ for (i=0; i < argc; i++) {
+ if (argv[i])
+ free(argv[i]);
+ }
+ free(argv);
+}
+
+static char **
+MakeUtf8Cmdline(int argc, const wchar_t **wargv)
+{
+ char ** argv;
+ int i;
+
+ argv = calloc(argc, sizeof(argv[0]));
+ if (argv == NULL)
+ return NULL;
+
+ for (i=0; i < argc; i++) {
+ int s;
+
+ s = WideCharToMultiByte(CP_UTF8, 0, wargv[i], -1, NULL, 0, NULL, FALSE);
+ if (s == 0 ||
+ (argv[i] = calloc(s+1, sizeof(char))) == NULL) {
+ break;
+ }
+
+ s = WideCharToMultiByte(CP_UTF8, 0, wargv[i], -1, argv[i], s+1, NULL, FALSE);
+ if (s == 0) {
+ break;
+ }
+ }
+
+ if (i < argc) {
+ FreeUtf8CmdLine(argc, argv);
+ return NULL;
+ }
+
+ return argv;
+}
+
+int wmain(int argc, wchar_t **wargv)
{
afs_int32 code;
struct cmd_syndesc *ts;
+ char ** argv;
#ifdef AFS_AIX32_ENV
/*
WSAStartup(0x0101, &WSAjunk);
#endif /* WIN32 */
+ argv = MakeUtf8Cmdline(argc, wargv);
+
/* try to find volume location information */
osi_Init();
cmd_AddParm(ts, "-volume", CMD_SINGLE, CMD_OPTIONAL, "volume name or number");
cmd_AddParm(ts, "-state", CMD_SINGLE, CMD_OPTIONAL, "new volume state: online, busy, offline, down");
+ ts = cmd_CreateSyntax("smbunicode", SmbUnicodeCmd, NULL, "enable or disable Unicode on new SMB connections");
+ cmd_AddParm(ts, "-on", CMD_FLAG, CMD_OPTIONAL, "enable Unicode on new connections");
+ cmd_AddParm(ts, "-off", CMD_FLAG, CMD_OPTIONAL, "disable Unicode on new connections");
+
code = cmd_Dispatch(argc, argv);
if (rxInitDone)
rx_Finalize();
+ FreeUtf8CmdLine(argc, argv);
+
return code;
}
/* there's a drive letter there */
firstp = pathp+2;
pathHasDrive = 1;
- }
- else {
+ } else {
firstp = pathp;
pathHasDrive = 0;
}
return 0;
}
- GetCurrentDirectory(sizeof(origPath), origPath);
+ GetCurrentDirectoryA(sizeof(origPath), origPath);
doSwitch = 0;
if (pathHasDrive && (*pathp & ~0x20) != (origPath[0] & ~0x20)) {
newPath[0] = *pathp;
newPath[1] = ':';
newPath[2] = 0;
- if (!SetCurrentDirectory(newPath)) {
+ if (!SetCurrentDirectoryA(newPath)) {
code = GetLastError();
return code;
}
}
/* now get the absolute path to the current wdir in this drive */
- GetCurrentDirectory(sizeof(tpath), tpath);
+ GetCurrentDirectoryA(sizeof(tpath), tpath);
strcpy(outPathp, tpath+2); /* skip drive letter */
/* if there is a non-null name after the drive, append it */
if (*firstp != 0) {
/* finally, if necessary, switch back to our home drive letter */
if (doSwitch) {
- SetCurrentDirectory(origPath);
+ SetCurrentDirectoryA(origPath);
}
return 0;
char *pmount=mountRoot;
DWORD len=sizeof(mountRoot)-1;
printf("int mountroot \n");
- if ((RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY, 0,
+ if ((RegOpenKeyExA(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY, 0,
(IsWow64()?KEY_WOW64_64KEY:0)|KEY_QUERY_VALUE, &parmKey)!= ERROR_SUCCESS)
- || (RegQueryValueEx(parmKey, "Mountroot", NULL, NULL,(LPBYTE)(mountRoot), &len)!= ERROR_SUCCESS)
+ || (RegQueryValueExA(parmKey, "Mountroot", NULL, NULL,(LPBYTE)(mountRoot), &len)!= ERROR_SUCCESS)
|| (len==sizeof(mountRoot)-1)
)
strcpy(mountRoot, "\\afs");
#include "smb.h"
#include "lanahelper.h"
+#define STRSAFE_NO_DEPRECATE
+#include <strsafe.h>
+
/* These characters are illegal in Windows filenames */
static char *illegalChars = "\\/:*?\"<>|";
/* hide dot files? */
int smb_hideDotFiles;
+/* Negotiate Unicode support? */
+LONG smb_UseUnicode;
+
/* global state about V3 protocols */
int smb_useV3; /* try to negotiate V3 */
smb_packetFreeListp = tbp->nextp;
lock_ReleaseWrite(&smb_globalLock);
if (!tbp) {
- tbp = calloc(65540,1);
+ tbp = calloc(sizeof(*tbp),1);
tbp->magic = SMB_PACKETMAGIC;
tbp->ncbp = NULL;
tbp->vcp = NULL;
tbp->ncb_length = 0;
tbp->flags = 0;
tbp->spacep = NULL;
-
+ tbp->stringsp = NULL;
}
osi_assertx(tbp->magic == SMB_PACKETMAGIC, "invalid smb_packet_t magic");
tbp = GetPacket();
memcpy(tbp, pkt, sizeof(smb_packet_t));
tbp->wctp = tbp->data + (unsigned int)(pkt->wctp - pkt->data);
+ tbp->stringsp = NULL;
if (tbp->vcp)
smb_HoldVC(tbp->vcp);
return tbp;
return ncbp;
}
+static void FreeSMBStrings(smb_packet_t * pkt)
+{
+ cm_space_t * s;
+ cm_space_t * ns;
+
+ for (s = pkt->stringsp; s; s = ns) {
+ ns = s->nextp;
+ cm_FreeSpace(s);
+ }
+ pkt->stringsp = NULL;
+}
+
void smb_FreePacket(smb_packet_t *tbp)
{
smb_vc_t * vcp = NULL;
tbp->oddByte = 0;
tbp->ncb_length = 0;
tbp->flags = 0;
+ FreeSMBStrings(tbp);
lock_ReleaseWrite(&smb_globalLock);
if (vcp)
*parmDatap++ = parmValue & 0xff;
}
+
+
void smb_StripLastComponent(char *outPathp, char **lastComponentp, char *inPathp)
{
char *lastSlashp;
}
}
-unsigned char *smb_ParseASCIIBlock(unsigned char *inp, char **chainpp)
+unsigned char *smb_ParseASCIIBlock(smb_packet_t * pktp, unsigned char *inp,
+ char **chainpp, int flags)
{
+ size_t cb;
+
if (*inp++ != 0x4)
return NULL;
+
+#ifdef SMB_UNICODE
+ if (!WANTS_UNICODE(pktp))
+ flags |= SMB_STRF_FORCEASCII;
+#endif
+
+ cb = sizeof(pktp->data) - (inp - pktp->data);
+ if (inp < pktp->data || inp >= pktp->data + sizeof(pktp->data)) {
+#ifdef DEBUG_UNICODE
+ DebugBreak();
+#endif
+ cb = sizeof(pktp->data);
+ }
+ 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)
+{
+ size_t cb;
+
+#ifdef SMB_UNICODE
+ if (!WANTS_UNICODE(pktp))
+ flags |= SMB_STRF_FORCEASCII;
+#endif
+
+ cb = sizeof(pktp->data) - (inp - pktp->data);
+ if (inp < pktp->data || inp >= pktp->data + sizeof(pktp->data)) {
+#ifdef DEBUG_UNICODE
+ DebugBreak();
+#endif
+ cb = sizeof(pktp->data);
+ }
+ 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)
+{
+#ifdef SMB_UNICODE
+ if (!WANTS_UNICODE(pktp))
+ flags |= SMB_STRF_FORCEASCII;
+#endif
+
+ 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)
+{
+ size_t cb = cch;
+
+#ifdef SMB_UNICODE
+ if (!WANTS_UNICODE(pktp))
+ flags |= SMB_STRF_FORCEASCII;
+ else
+ cb = cch * sizeof(wchar_t);
+#endif
+
+ 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)
+{
+#ifdef SMB_UNICODE
+ if (!(flags & SMB_STRF_FORCEASCII)) {
+ size_t cch_src;
+ int cb_dest;
+ cm_space_t * spacep;
+ int null_terms = 0;
+
+ if (bufbase && ((inp - bufbase) % 2) != 0) {
+ inp++; /* unicode strings are always word aligned */
+ }
+
+ if (*pcb_max > 0) {
+ if (FAILED(StringCchLengthW((const wchar_t *) inp, *pcb_max / sizeof(wchar_t),
+ &cch_src))) {
+ cch_src = *pcb_max / sizeof(wchar_t);
+ *pcb_max = 0;
+ null_terms = 0;
+ } else {
+ *pcb_max -= (cch_src + 1) * sizeof(wchar_t);
+ null_terms = 1;
+ }
+ } else {
+ return NULL;
+ }
+
+ spacep = cm_GetSpace();
+ spacep->nextp = *stringspp;
+ *stringspp = spacep;
+
+ if (cch_src == 0) {
+ if (chainpp) {
+ *chainpp = inp + sizeof(wchar_t);
+ }
+
+ spacep->data[0] = '\0';
+ return spacep->data;
+ }
+
+ 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;
+ }
+
+ 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;
+
+ } else {
+#endif
+ /* Not using Unicode */
if (chainpp) {
- *chainpp = inp + strlen(inp) + 1; /* skip over null-terminated string */
+ *chainpp = inp + strlen(inp) + 1;
}
+ if ((flags & SMB_STRF_ANSIPATH) && smb_StoreAnsiFilenames)
+ OemToChar(inp, inp);
return inp;
+#ifdef SMB_UNICODE
+ }
+#endif
+}
+
+unsigned char * smb_UnparseString(smb_packet_t * pktp, unsigned char * outp,
+ unsigned char * 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 ((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);
+ }
+
+ 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 (plen)
+ *plen = sizeof(wchar_t) * ((flags & SMB_STRF_IGNORENULL)? nchars - 1 : nchars);
+
+ return (unsigned char *) 1; /* return TRUE if we are using unicode */
+ }
+ else
+#endif
+ {
+ /* Storing ANSI */
+ size_t len;
+
+ len = strlen(str);
+ if (plen)
+ *plen = ((flags & SMB_STRF_IGNORENULL)? len: len+1);
+
+ return NULL;
+ }
+ }
+
+ /* Number of bytes left in the buffer. */
+ if (outp >= pktp->data && outp < pktp->data + sizeof(pktp->data)) {
+ align = ((outp - pktp->data) % 2);
+ buffersize = (pktp->data + sizeof(pktp->data)) - ((char *) outp);
+ } else {
+ align = (((size_t) outp) % 2);
+ buffersize = sizeof(pktp->data);
+ }
+
+#ifdef SMB_UNICODE
+
+ if (WANTS_UNICODE(pktp) && !(flags & SMB_STRF_FORCEASCII)) {
+ int nchars;
+
+ if (align)
+ *outp++ = '\0';
+
+ if (*str == '\0') {
+
+ if (buffersize < sizeof(wchar_t))
+ return NULL;
+
+ *((wchar_t *) outp) = L'\0';
+ if (plen && !(flags & SMB_STRF_IGNORENULL))
+ *plen += sizeof(wchar_t);
+ 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);
+ }
+
+ 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),
+ GetLastError());
+ return NULL;
+ }
+
+ if (plen)
+ *plen += sizeof(wchar_t) * ((flags & SMB_STRF_IGNORENULL)? nchars - 1: nchars);
+
+ return outp + sizeof(wchar_t) * nchars;
+ }
+ else
+#endif
+ {
+ /* Storing ANSI */
+ size_t len;
+
+ len = strlen(str); len++;
+ if (len > buffersize)
+ return NULL;
+
+ strcpy(outp, str);
+ if (plen)
+ *plen += ((flags & SMB_STRF_IGNORENULL)? len - 1: len);
+
+ return outp + len;
+ }
}
unsigned char *smb_ParseVblBlock(unsigned char *inp, char **chainpp, int *lengthp)
return inp;
}
+unsigned char *smb_ParseDataBlock(unsigned char *inp, char **chainpp, int *lengthp)
+{
+ int tlen;
+
+ if (*inp++ != 0x1) return NULL;
+ tlen = inp[0] + (inp[1]<<8);
+ inp += 2; /* skip length field */
+
+ if (chainpp) {
+ *chainpp = inp + tlen;
+ }
+
+ if (lengthp) *lengthp = tlen;
+
+ return inp;
+}
+
/* format a packet as a response */
void smb_FormatResponsePacket(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *op)
{
outp->reb |= SMB_FLAGS_CANONICAL_PATHNAMES;
#endif
outp->flg2 = SMB_FLAGS2_KNOWS_LONG_NAMES;
+#ifdef SMB_UNICODE
+ if ((vcp->flags & SMB_VCFLAG_USEUNICODE) == SMB_VCFLAG_USEUNICODE)
+ outp->flg2 |= SMB_FLAGS2_UNICODE;
+#endif
/* copy fields in generic packet area */
op->wctp = &outp->wct;
return CM_ERROR_BADOP;
}
+/* SMB_COM_ECHO */
long smb_ReceiveCoreEcho(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
unsigned short EchoCount, i;
return 0;
}
+/* SMB_COM_READ_RAW */
long smb_ReceiveCoreReadRaw(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
osi_hyper_t offset;
return 0;
}
+/* SMB_COM_NEGOTIATE */
long smb_ReceiveNegotiate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
char *namep;
* and NT Find *
* and NT SMB's *
* and raw mode
- * and DFS */
+ * and DFS
+ * and Unicode */
caps = NTNEGOTIATE_CAPABILITY_NTSTATUS |
#ifdef DFS_SUPPORT
NTNEGOTIATE_CAPABILITY_DFS |
if ( smb_authType == SMB_AUTH_EXTENDED )
caps |= NTNEGOTIATE_CAPABILITY_EXTENDED_SECURITY;
+#ifdef SMB_UNICODE
+ if ( smb_UseUnicode ) {
+ caps |= NTNEGOTIATE_CAPABILITY_UNICODE;
+ }
+#endif
+
smb_SetSMBParmLong(outp, 9, caps);
time(&unixTime);
smb_SearchTimeFromUnixTime(&dosTime, unixTime);
return 0;
}
+/* SMB_COM_TREE_CONNECT */
long smb_ReceiveCoreTreeConnect(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *rsp)
{
smb_tid_t *tidp;
int shareFound;
char *tp;
char *pathp;
- char *passwordp;
cm_user_t *userp;
osi_Log0(smb_logp, "SMB receive tree connect");
/* parse input parameters */
tp = smb_GetSMBData(inp, NULL);
- pathp = smb_ParseASCIIBlock(tp, &tp);
- if (smb_StoreAnsiFilenames)
- OemToChar(pathp,pathp);
- passwordp = smb_ParseASCIIBlock(tp, &tp);
+ pathp = smb_ParseASCIIBlock(inp, tp, &tp, SMB_STRF_ANSIPATH);
tp = strrchr(pathp, '\\');
if (!tp)
return CM_ERROR_BADSMB;
return 0;
}
-unsigned char *smb_ParseDataBlock(unsigned char *inp, char **chainpp, int *lengthp)
-{
- int tlen;
-
- if (*inp++ != 0x1) return NULL;
- tlen = inp[0] + (inp[1]<<8);
- inp += 2; /* skip length field */
-
- if (chainpp) {
- *chainpp = inp + tlen;
- }
-
- if (lengthp) *lengthp = tlen;
-
- return inp;
-}
-
/* set maskp to the mask part of the incoming path.
* Mask is 11 bytes long (8.3 with the dot elided).
* Returns true if succeeds with a valid name, otherwise it does
return pathp; /* no slash, return the entire path */
}
+/* SMB_COM_SEARCH for a volume label
+
+ (This is called from smb_ReceiveCoreSearchDir() and not an actual
+ dispatch function.) */
long smb_ReceiveCoreSearchVolume(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
unsigned char *pathp;
/* pull pathname and stat block out of request */
tp = smb_GetSMBData(inp, NULL);
- pathp = smb_ParseASCIIBlock(tp, (char **) &tp);
+ pathp = smb_ParseASCIIBlock(inp, tp, (char **) &tp,
+ SMB_STRF_ANSIPATH|SMB_STRF_FORCEASCII);
osi_assertx(pathp != NULL, "null path");
- if (smb_StoreAnsiFilenames)
- OemToChar(pathp,pathp);
statBlockp = smb_ParseVblBlock(tp, (char **) &tp, &statLen);
osi_assertx(statBlockp != NULL, "null statBlock");
if (statLen == 0) {
*tp++ = 0;
*tp++ = 0;
+ /* The filename is a UCHAR buffer that is ASCII even if Unicode
+ was negotiated. */
+
/* finally, null-terminated 8.3 pathname, which we set to AFS */
memset(tp, ' ', 13);
strcpy(tp, "AFS");
return code;
}
+/* SMB_COM_SEARCH */
long smb_ReceiveCoreSearchDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
int attribute;
caseFold = CM_FLAG_CASEFOLD;
tp = smb_GetSMBData(inp, NULL);
- pathp = smb_ParseASCIIBlock(tp, &tp);
- if (smb_StoreAnsiFilenames)
- OemToChar(pathp,pathp);
+ pathp = smb_ParseASCIIBlock(inp, tp, &tp,
+ SMB_STRF_ANSIPATH|SMB_STRF_FORCEASCII);
inCookiep = smb_ParseVblBlock(tp, &tp, &dataLength);
/* bail out if request looks bad */
strncpy(op, actualName, 13);
if (smb_StoreAnsiFilenames)
CharToOem(op, op);
+ /* This is a UCHAR field, which is ASCII even if Unicode
+ is negotiated. */
/* Uppercase if requested by client */
if (!KNOWS_LONG_NAMES(inp))
return code;
}
+
/* verify that this is a valid path to a directory. I don't know why they
* don't use the get file attributes call.
+ *
+ * SMB_COM_CHECK_DIRECTORY
*/
long smb_ReceiveCoreCheckPath(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
cm_InitReq(&req);
pathp = smb_GetSMBData(inp, NULL);
- pathp = smb_ParseASCIIBlock(pathp, NULL);
+ pathp = smb_ParseASCIIBlock(inp, pathp, NULL, SMB_STRF_ANSIPATH);
if (!pathp)
return CM_ERROR_BADFD;
- if (smb_StoreAnsiFilenames)
- OemToChar(pathp,pathp);
osi_Log1(smb_logp, "SMB receive check path %s",
osi_LogSaveString(smb_logp, pathp));
return code;
}
+/* SMB_COM_SET_INFORMATION */
long smb_ReceiveCoreSetFileAttributes(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
char *pathp;
dosTime = smb_GetSMBParm(inp, 1) | (smb_GetSMBParm(inp, 2) << 16);
pathp = smb_GetSMBData(inp, NULL);
- pathp = smb_ParseASCIIBlock(pathp, NULL);
+ pathp = smb_ParseASCIIBlock(inp, pathp, NULL, SMB_STRF_ANSIPATH);
if (!pathp)
return CM_ERROR_BADSMB;
- if (smb_StoreAnsiFilenames)
- OemToChar(pathp,pathp);
osi_Log2(smb_logp, "SMB receive setfile attributes time %d, attr 0x%x",
dosTime, attribute);
return code;
}
+
long smb_ReceiveCoreGetFileAttributes(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
char *pathp;
cm_InitReq(&req);
pathp = smb_GetSMBData(inp, NULL);
- pathp = smb_ParseASCIIBlock(pathp, NULL);
+ pathp = smb_ParseASCIIBlock(inp, pathp, NULL, SMB_STRF_ANSIPATH);
if (!pathp)
return CM_ERROR_BADSMB;
if (*pathp == 0) /* null path */
pathp = "\\";
- else
- if (smb_StoreAnsiFilenames)
- OemToChar(pathp,pathp);
osi_Log1(smb_logp, "SMB receive getfile attributes path %s",
osi_LogSaveString(smb_logp, pathp));
return 0;
}
+/* SMB_COM_TREE_DISCONNECT */
long smb_ReceiveCoreTreeDisconnect(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
smb_tid_t *tidp;
return 0;
}
+/* SMB_COM_0PEN */
long smb_ReceiveCoreOpen(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
smb_fid_t *fidp;
cm_InitReq(&req);
pathp = smb_GetSMBData(inp, NULL);
- pathp = smb_ParseASCIIBlock(pathp, NULL);
- if (smb_StoreAnsiFilenames)
- OemToChar(pathp,pathp);
+ pathp = smb_ParseASCIIBlock(inp, pathp, NULL, SMB_STRF_ANSIPATH);
osi_Log1(smb_logp, "SMB receive open file [%s]", osi_LogSaveString(smb_logp, pathp));
return code;
}
+/* SMB_COM_DELETE */
long smb_ReceiveCoreUnlink(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
int attribute;
attribute = smb_GetSMBParm(inp, 0);
tp = smb_GetSMBData(inp, NULL);
- pathp = smb_ParseASCIIBlock(tp, &tp);
- if (smb_StoreAnsiFilenames)
- OemToChar(pathp,pathp);
+ pathp = smb_ParseASCIIBlock(inp, tp, &tp, SMB_STRF_ANSIPATH);
osi_Log1(smb_logp, "SMB receive unlink %s",
osi_LogSaveString(smb_logp, pathp));
return code;
}
+/* SMB_COM_RENAME */
long
smb_ReceiveCoreRename(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
long code;
tp = smb_GetSMBData(inp, NULL);
- oldPathp = smb_ParseASCIIBlock(tp, &tp);
- if (smb_StoreAnsiFilenames)
- OemToChar(oldPathp,oldPathp);
- newPathp = smb_ParseASCIIBlock(tp, &tp);
- if (smb_StoreAnsiFilenames)
- OemToChar(newPathp,newPathp);
+ 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),
return 0;
}
+
long smb_ReceiveCoreRemoveDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
long code = 0;
cm_InitReq(&req);
tp = smb_GetSMBData(inp, NULL);
- pathp = smb_ParseASCIIBlock(tp, &tp);
- if (smb_StoreAnsiFilenames)
- OemToChar(pathp,pathp);
+ pathp = smb_ParseASCIIBlock(inp, tp, &tp, SMB_STRF_ANSIPATH);
spacep = inp->spacep;
smb_StripLastComponent(spacep->data, &lastNamep, pathp);
return code;
}
+/* SMB_COM_FLUSH */
long smb_ReceiveCoreFlush(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
unsigned short fid;
return code;
}
+/* SMB_COM_CLOSE */
long smb_ReceiveCoreClose(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
unsigned short fid;
return code;
}
+/* SMB_COM_WRITE */
long smb_ReceiveCoreWrite(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
unsigned short fd;
return 0;
}
+/* SMB_COM_WRITE_RAW */
long smb_ReceiveCoreWriteRaw(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp, raw_write_cont_t *rwcp)
{
osi_hyper_t offset;
return 0;
}
+/* SMB_COM_READ */
long smb_ReceiveCoreRead(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
osi_hyper_t offset;
return code;
}
+/* SMB_COM_CREATE_DIRECTORY */
long smb_ReceiveCoreMakeDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
char *pathp;
initialModeBits = 0777;
tp = smb_GetSMBData(inp, NULL);
- pathp = smb_ParseASCIIBlock(tp, &tp);
- if (smb_StoreAnsiFilenames)
- OemToChar(pathp,pathp);
+ pathp = smb_ParseASCIIBlock(inp, tp, &tp, SMB_STRF_ANSIPATH);
if (strcmp(pathp, "\\") == 0)
return CM_ERROR_EXISTS;
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;
initialModeBits &= ~0222;
tp = smb_GetSMBData(inp, NULL);
- pathp = smb_ParseASCIIBlock(tp, &tp);
- if (smb_StoreAnsiFilenames)
- OemToChar(pathp,pathp);
+ pathp = smb_ParseASCIIBlock(inp, tp, &tp, SMB_STRF_ANSIPATH);
spacep = inp->spacep;
smb_StripLastComponent(spacep->data, &lastNamep, pathp);
return 0;
}
+/* SMB_COM_SEEK */
long smb_ReceiveCoreSeek(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
long code = 0;
/* Raw Write */
code = smb_ReceiveCoreWriteRaw (vcp, inp, outp, rwcp);
else {
- osi_Log4(smb_logp,"Dispatch %s vcp 0x%p lana %d lsn %d",opName,vcp,vcp->lana,vcp->lsn);
+ osi_Log4(smb_logp,"Dispatch %s vcp 0x%p lana %d lsn %d",
+ opName,vcp,vcp->lana,vcp->lsn);
code = (*(dp->procp)) (vcp, inp, outp);
- osi_Log4(smb_logp,"Dispatch return code 0x%x vcp 0x%p lana %d lsn %d",code,vcp,vcp->lana,vcp->lsn);
+ osi_Log4(smb_logp,"Dispatch return code 0x%x vcp 0x%p lana %d lsn %d",
+ code,vcp,vcp->lana,vcp->lsn);
#ifdef LOG_PACKET
if ( code == CM_ERROR_BADSMB ||
code == CM_ERROR_BADOP )
osi_Log3(smb_logp, "Request %s straddled session startup, "
"took %d ms, ncb length %d", opName, newTime - oldTime, ncbp->ncb_length);
}
- }
- else {
+
+ FreeSMBStrings(inp);
+ } else {
/* bad opcode, fail the request, after displaying it */
osi_Log1(smb_logp, "Received bad SMB req 0x%X", inp->inCom);
#ifdef LOG_PACKET
smbp = (smb_t *)bufp->data;
outbufp->flags = 0;
+#ifndef NOTRACE
__try
{
+#endif
if (smbp->com == 0x1d) {
/* Special handling for Write Raw */
raw_write_cont_t rwc;
/* TODO: what else needs to be serialized? */
smb_DispatchPacket(vcp, bufp, outbufp, ncbp, NULL);
}
+#ifndef NOTRACE
}
__except( smb_ServerExceptionFilter() ) {
}
+#endif
smb_concurrentCalls--;
smbp->errHigh = (unsigned char) ((errCode >> 8) & 0xff);
smbp->rcls = errClass;
}
+
smb_SendPacket(vcp, outp);
smb_FreePacket(outp);
void smb_LogPacket(smb_packet_t *packet)
{
BYTE *vp, *cp;
+ smb_t * smbp;
unsigned length, paramlen, datalen, i, j;
char buf[81];
char hex[]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
osi_Log0(smb_logp, "*** SMB packet dump ***");
+ smbp = (smb_t *) packet->data;
vp = (BYTE *) packet->data;
- datalen = *((WORD*)(vp + (paramlen = ((unsigned)*(vp+20)) << 1)));
- length = paramlen + 2 + datalen;
-
+ paramlen = smbp->wct * 2;
+ datalen = *((WORD *) (smbp->vdata + paramlen));
+ length = sizeof(*smbp) + paramlen + 1 + datalen;
for (i=0;i < length; i+=16)
{
#define KNOWS_LONG_NAMES(inp) ((((smb_t *)inp)->flg2 & SMB_FLAGS2_KNOWS_LONG_NAMES)?1:0)
#define WANTS_DFS_PATHNAMES(inp) ((((smb_t *)inp)->flg2 & SMB_FLAGS2_DFS_PATHNAMES)?1:0)
+#define WANTS_UNICODE(inp) ((((smb_t *)inp)->flg2 & SMB_FLAGS2_UNICODE)?1:0)
/* Information Levels */
#define SMB_INFO_STANDARD 1
#define SMB_PACKETSIZE 32768 /* was 8400 */
/* raw mode is considered obsolete and cannot be used with message signing */
#define SMB_MAXRAWSIZE 65536
+/* max STRING characters per packet per request */
+#define SMB_STRINGBUFSIZE 4096
/* Negotiate protocol constants */
/* Security */
unsigned char oddByte;
unsigned short ncb_length;
unsigned char flags;
+ cm_space_t *stringsp; /* decoded strings from this packet */
} smb_packet_t;
/* smb_packet flags */
#define SMB_VCFLAG_SESSX_RCVD 0x40 /* we received at least one session setups on this vc */
#define SMB_VCFLAG_AUTH_IN_PROGRESS 0x80 /* a SMB NT extended authentication is in progress */
#define SMB_VCFLAG_CLEAN_IN_PROGRESS 0x100
+#define SMB_VCFLAG_USEUNICODE 0x200 /* une UNICODE for STRING fields (NTLM 0.12 or later) */
/* one per user session */
typedef struct smb_user {
/* uid pointer */
smb_user_t *uidp;
+
} smb_ioctl_t;
/* flags for smb_ioctl_t */
#define SMB_IOCTLFLAG_DATAIN 1 /* reading data from client to server */
#define SMB_IOCTLFLAG_LOGON 2 /* got tokens from integrated logon */
+#define SMB_IOCTLFLAG_USEUTF8 4 /* this request is using UTF-8 strings */
/* one per file ID; these are really file descriptors */
typedef struct smb_fid {
extern void smb_StripLastComponent(char *outPathp, char **lastComponentp,
char *inPathp);
-extern unsigned char *smb_ParseASCIIBlock(unsigned char *inp, char **chainpp);
+#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 unsigned char *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 unsigned char *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 unsigned char * smb_UnparseString(smb_packet_t * pktp, unsigned char * outp,
+ unsigned char * str,
+ size_t * plen, int flags);
extern unsigned char *smb_ParseVblBlock(unsigned char *inp, char **chainpp,
int *lengthp);
extern int smb_ServerLanManagerLength;
extern GUID smb_ServerGUID;
extern LSA_STRING smb_lsaLogonOrigin;
+extern LONG smb_UseUnicode;
/* used for getting a challenge for SMB auth */
typedef struct _MSV1_0_LM20_CHALLENGE_REQUEST {
extern unsigned char *smb_ParseDataBlock(unsigned char *inp, char **chainpp, int *lengthp);
-extern unsigned char *smb_ParseASCIIBlock(unsigned char *inp, char **chainpp);
-
extern unsigned char *smb_ParseVblBlock(unsigned char *inp, char **chainpp, int *lengthp);
extern int smb_SUser(cm_user_t *userp);
return 0;
}
-unsigned char *smb_ParseString(unsigned char *inp, char **chainpp)
-{
- if (chainpp) {
- /* skip over null-terminated string */
- *chainpp = inp + strlen(inp) + 1;
- }
- return inp;
-}
-
void OutputDebugF(char * format, ...) {
va_list args;
int len;
* sending a session setup packet, which means that we can't rely on a
* UID in subsequent packets. Though in practice we get one anyway.
*/
+/* SMB_COM_SESSION_SETUP_ANDX */
long smb_ReceiveV3SessionSetupX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
char *tp;
code = smb_AuthenticateUserExt(vcp, usern, secBlobIn, secBlobInLength, &secBlobOut, &secBlobOutLength);
if (code == CM_ERROR_GSSCONTINUE) {
+ size_t cb_data = 0;
+
smb_SetSMBParm(outp, 2, 0);
smb_SetSMBParm(outp, 3, secBlobOutLength);
- smb_SetSMBDataLength(outp, secBlobOutLength + smb_ServerOSLength + smb_ServerLanManagerLength + smb_ServerDomainNameLength);
+
tp = smb_GetSMBData(outp, NULL);
if (secBlobOutLength) {
memcpy(tp, secBlobOut, secBlobOutLength);
free(secBlobOut);
tp += secBlobOutLength;
+ cb_data += secBlobOutLength;
}
- memcpy(tp,smb_ServerOS,smb_ServerOSLength);
- tp += smb_ServerOSLength;
- memcpy(tp,smb_ServerLanManager,smb_ServerLanManagerLength);
- tp += smb_ServerLanManagerLength;
- memcpy(tp,smb_ServerDomainName,smb_ServerDomainNameLength);
- tp += smb_ServerDomainNameLength;
+ tp = smb_UnparseString(outp, tp, smb_ServerOS, &cb_data, 0);
+ tp = smb_UnparseString(outp, tp, smb_ServerLanManager, &cb_data, 0);
+ tp = smb_UnparseString(outp, tp, smb_ServerDomainName, &cb_data, 0);
+
+ smb_SetSMBDataLength(outp, cb_data);
}
/* TODO: handle return code and continue auth. Also free secBlobOut if applicable. */
csPwd = tp;
tp += csPwdLength;
- accountName = smb_ParseString(tp, &tp);
- primaryDomain = smb_ParseString(tp, NULL);
+ accountName = smb_ParseString(inp, tp, &tp, 0);
+ primaryDomain = smb_ParseString(inp, tp, NULL, 0);
OutputDebugF("Account Name: %s",accountName);
OutputDebugF("Primary Domain: %s", primaryDomain);
ciPwd = tp;
tp += ciPwdLength;
- accountName = smb_ParseString(tp, &tp);
- primaryDomain = smb_ParseString(tp, NULL);
+ accountName = smb_ParseString(inp, tp, &tp, 0);
+ primaryDomain = smb_ParseString(inp, tp, NULL, 0);
OutputDebugF("Account Name: %s",accountName);
OutputDebugF("Primary Domain: %s", primaryDomain);
if (caps & NTNEGOTIATE_CAPABILITY_NTSTATUS) {
vcp->flags |= SMB_VCFLAG_STATUS32;
}
+
+#ifdef SMB_UNICODE
+ if ((caps & NTNEGOTIATE_CAPABILITY_UNICODE) && smb_UseUnicode) {
+ vcp->flags |= SMB_VCFLAG_USEUNICODE;
+ }
+#endif
lock_ReleaseMutex(&vcp->mx);
}
if (vcp->flags & SMB_VCFLAG_USENT) {
if (smb_authType == SMB_AUTH_EXTENDED) {
+ size_t cb_data = 0;
+
smb_SetSMBParm(outp, 3, secBlobOutLength);
- smb_SetSMBDataLength(outp, secBlobOutLength + smb_ServerOSLength + smb_ServerLanManagerLength + smb_ServerDomainNameLength);
+
tp = smb_GetSMBData(outp, NULL);
if (secBlobOutLength) {
memcpy(tp, secBlobOut, secBlobOutLength);
free(secBlobOut);
tp += secBlobOutLength;
+ cb_data += secBlobOutLength;
}
- memcpy(tp,smb_ServerOS,smb_ServerOSLength);
- tp += smb_ServerOSLength;
- memcpy(tp,smb_ServerLanManager,smb_ServerLanManagerLength);
- tp += smb_ServerLanManagerLength;
- memcpy(tp,smb_ServerDomainName,smb_ServerDomainNameLength);
- tp += smb_ServerDomainNameLength;
+
+ tp = smb_UnparseString(outp, tp, smb_ServerOS, &cb_data, 0);
+ tp = smb_UnparseString(outp, tp, smb_ServerLanManager, &cb_data, 0);
+ tp = smb_UnparseString(outp, tp, smb_ServerDomainName, &cb_data, 0);
+
+ smb_SetSMBDataLength(outp, cb_data);
} else {
smb_SetSMBDataLength(outp, 0);
}
} else {
if (smb_authType == SMB_AUTH_EXTENDED) {
- smb_SetSMBDataLength(outp, smb_ServerOSLength + smb_ServerLanManagerLength + smb_ServerDomainNameLength);
+ size_t cb_data = 0;
+
tp = smb_GetSMBData(outp, NULL);
- memcpy(tp,smb_ServerOS,smb_ServerOSLength);
- tp += smb_ServerOSLength;
- memcpy(tp,smb_ServerLanManager,smb_ServerLanManagerLength);
- tp += smb_ServerLanManagerLength;
- memcpy(tp,smb_ServerDomainName,smb_ServerDomainNameLength);
- tp += smb_ServerDomainNameLength;
+
+ tp = smb_UnparseString(outp, tp, smb_ServerOS, &cb_data, 0);
+ tp = smb_UnparseString(outp, tp, smb_ServerLanManager, &cb_data, 0);
+ tp = smb_UnparseString(outp, tp, smb_ServerDomainName, &cb_data, 0);
+
+ smb_SetSMBDataLength(outp, cb_data);
} else {
smb_SetSMBDataLength(outp, 0);
}
return 0;
}
+/* SMB_COM_LOGOFF_ANDX */
long smb_ReceiveV3UserLogoffX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
smb_user_t *uidp;
#define SMB_SUPPORT_SEARCH_BITS 0x0001
#define SMB_SHARE_IS_IN_DFS 0x0002
+/* SMB_COM_TREE_CONNECT_ANDX */
long smb_ReceiveV3TreeConnectX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
smb_tid_t *tidp;
/* parse input parameters */
tp = smb_GetSMBData(inp, NULL);
- passwordp = smb_ParseString(tp, &tp);
- pathp = smb_ParseString(tp, &tp);
- if (smb_StoreAnsiFilenames)
- OemToChar(pathp,pathp);
- servicep = smb_ParseString(tp, &tp);
+ passwordp = smb_ParseString(inp, tp, &tp, SMB_STRF_FORCEASCII);
+ pathp = smb_ParseString(inp, tp, &tp, SMB_STRF_ANSIPATH);
+ servicep = smb_ParseString(inp, tp, &tp, SMB_STRF_FORCEASCII);
tp = strrchr(pathp, '\\');
if (!tp) {
}
strcpy(shareName, tp+1);
- osi_Log2(smb_logp, "Tree connect pathp[%s] shareName[%s]",
+ 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, shareName),
+ osi_LogSaveString(smb_logp, servicep));
if (strcmp(servicep, "IPC") == 0 || strcmp(shareName, "IPC$") == 0) {
#ifndef NO_IPC
((smb_t *)inp)->tid = newTid;
tp = smb_GetSMBData(outp, NULL);
if (!ipc) {
- /* XXX - why is this a drive letter? */
- *tp++ = 'A';
- *tp++ = ':';
- *tp++ = 0;
- *tp++ = 'A';
- *tp++ = 'F';
- *tp++ = 'S';
- *tp++ = 0;
- smb_SetSMBDataLength(outp, 7);
+ 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);
+ smb_SetSMBDataLength(outp, cb_data);
} else {
- strcpy(tp, "IPC");
- smb_SetSMBDataLength(outp, 4);
+ size_t cb_data = 0;
+
+ tp = smb_UnparseString(outp, tp, "IPC", &cb_data, SMB_STRF_FORCEASCII);
+ smb_SetSMBDataLength(outp, cb_data);
}
osi_Log1(smb_logp, "SMB3 tree connect created ID %d", newTid);
tp->com = 0x32;
}
tp->flags |= SMB_TRAN2PFLAG_ALLOC;
+#ifdef SMB_UNICODE
+ if (WANTS_UNICODE(inp) && (vcp->flags & SMB_VCFLAG_USEUNICODE))
+ tp->flags |= SMB_TRAN2PFLAG_USEUNICODE;
+#endif
return tp;
}
if (t2p->datap)
free(t2p->datap);
}
+ while (t2p->stringsp) {
+ cm_space_t * ns;
+
+ ns = t2p->stringsp;
+ t2p->stringsp = ns->nextp;
+ cm_FreeSpace(ns);
+ }
free(t2p);
}
+unsigned char *smb_ParseStringT2Parm(smb_tran2Packet_t * p, unsigned char * inp,
+ char ** chainpp, int flags)
+{
+ size_t cb;
+
+#ifdef SMB_UNICODE
+ if (!(p->flags & SMB_TRAN2PFLAG_USEUNICODE))
+ 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) {
+ DebugBreak();
+ cb = p->totalParms;
+ }
+
+ return smb_ParseStringBuf((unsigned char *) p->parmsp, &p->stringsp,
+ inp, &cb, chainpp, flags);
+}
+
/* called with a VC, an input packet to respond to, and an error code.
* sends an error response.
*/
smb_SendPacket(vcp, tp);
}
+
+/* SMB_COM_TRANSACTION and SMB_COM_TRANSACTION_SECONDARY */
long smb_ReceiveV3Trans(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
smb_tran2Packet_t *asp;
return 0;
}
-/* ANSI versions. The unicode versions support arbitrary length
- share names, but we don't support unicode yet. */
+/* ANSI versions. */
+
+#pragma pack(push, 1)
typedef struct smb_rap_share_info_0 {
- char shi0_netname[13];
+ BYTE shi0_netname[13];
} smb_rap_share_info_0_t;
typedef struct smb_rap_share_info_1 {
- char shi1_netname[13];
- char shi1_pad;
+ BYTE shi1_netname[13];
+ BYTE shi1_pad;
WORD shi1_type;
DWORD shi1_remark; /* char *shi1_remark; data offset */
} smb_rap_share_info_1_t;
typedef struct smb_rap_share_info_2 {
- char shi2_netname[13];
- char shi2_pad;
- unsigned short shi2_type;
+ BYTE shi2_netname[13];
+ BYTE shi2_pad;
+ WORD shi2_type;
DWORD shi2_remark; /* char *shi2_remark; data offset */
- unsigned short shi2_permissions;
- unsigned short shi2_max_uses;
- unsigned short shi2_current_uses;
+ WORD shi2_permissions;
+ WORD shi2_max_uses;
+ WORD shi2_current_uses;
DWORD shi2_path; /* char *shi2_path; data offset */
- unsigned short shi2_passwd[9];
- unsigned short shi2_pad2;
+ WORD shi2_passwd[9];
+ WORD shi2_pad2;
} smb_rap_share_info_2_t;
#define SMB_RAP_MAX_SHARES 512
smb_rap_share_info_0_t * shares;
} smb_rap_share_list_t;
+#pragma pack(pop)
+
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;
return 0;
}
+/* RAP NetShareEnumRequest */
long smb_ReceiveRAPNetShareEnum(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op)
{
smb_tran2Packet_t *outp;
osi_hyper_t thyper;
tp = p->parmsp + 1; /* skip over function number (always 0) */
- (void) smb_ParseString((char *) tp, (char **) &tp); /* skip over parm descriptor */
- (void) smb_ParseString((char *) tp, (char **) &tp); /* skip over data descriptor */
+
+ {
+ char * cdescp;
+
+ cdescp = smb_ParseStringT2Parm(p, (char *) tp, (char **) &tp, SMB_STRF_FORCEASCII);
+ if (strcmp(cdescp, "WrLeh"))
+ return CM_ERROR_INVAL;
+ cdescp = smb_ParseStringT2Parm(p, (char *) tp, (char **) &tp, SMB_STRF_FORCEASCII);
+ if (strcmp(cdescp, "B13BWz"))
+ return CM_ERROR_INVAL;
+ }
+
infoLevel = tp[0];
bufsize = tp[1];
return CM_ERROR_INVAL;
}
+ /* We are supposed to use the same ASCII data structure even if
+ Unicode is negotiated, which ultimately means that the share
+ names that we return must be at most 13 characters in length,
+ including the NULL terminator.
+
+ The RAP specification states that shares with names longer than
+ 12 characters should not be included in the enumeration.
+ However, since we support prefix cell references and since many
+ cell names are going to exceed 12 characters, we lie and send
+ the first 12 characters.
+ */
+
/* first figure out how many shares there are */
rv = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY, 0,
KEY_QUERY_VALUE, &hkParam);
for (dw=0; dw < nRegShares && cshare < nSharesRet; dw++) {
len = sizeof(thisShare);
rv = RegEnumValue(hkSubmount, dw, thisShare, &len, NULL, NULL, NULL, NULL);
- if (rv == ERROR_SUCCESS && strlen(thisShare) && (!allSubmount || stricmp(thisShare,"all"))) {
- strncpy(shares[cshare].shi1_netname, thisShare, sizeof(shares->shi1_netname)-1);
+ if (rv == ERROR_SUCCESS &&
+ strlen(thisShare) && (!allSubmount || stricmp(thisShare,"all"))) {
+ strncpy(shares[cshare].shi1_netname, thisShare,
+ sizeof(shares->shi1_netname)-1);
shares[cshare].shi1_netname[sizeof(shares->shi1_netname)-1] = 0; /* unfortunate truncation */
shares[cshare].shi1_remark = (DWORD)(cstrp - outp->datap);
cshare++;
return code;
}
+/* RAP NetShareGetInfo */
long smb_ReceiveRAPNetShareGetInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op)
{
smb_tran2Packet_t *outp;
cm_InitReq(&req);
tp = p->parmsp + 1; /* skip over function number (always 1) */
- (void) smb_ParseString( (char *) tp, (char **) &tp); /* skip over param descriptor */
- (void) smb_ParseString( (char *) tp, (char **) &tp); /* skip over data descriptor */
- shareName = smb_ParseString( (char *) tp, (char **) &tp);
+
+ {
+ char * cdescp;
+
+ cdescp = smb_ParseStringT2Parm(p, (char *) tp, (char **) &tp, SMB_STRF_FORCEASCII);
+ if (strcmp(cdescp, "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"))
+
+ return CM_ERROR_INVAL;
+ }
+ shareName = smb_ParseStringT2Parm(p, (char *) tp, (char **) &tp, SMB_STRF_FORCEASCII);
+
infoLevel = *tp++;
bufsize = *tp++;
return code;
}
+#pragma pack(push, 1)
+
typedef struct smb_rap_wksta_info_10 {
DWORD wki10_computername; /*char *wki10_computername;*/
DWORD wki10_username; /* char *wki10_username; */
DWORD wki10_langroup; /* char *wki10_langroup;*/
- unsigned char wki10_ver_major;
- unsigned char wki10_ver_minor;
+ BYTE wki10_ver_major;
+ BYTE wki10_ver_minor;
DWORD wki10_logon_domain; /*char *wki10_logon_domain;*/
DWORD wki10_oth_domains; /* char *wki10_oth_domains;*/
} smb_rap_wksta_info_10_t;
+#pragma pack(pop)
long smb_ReceiveRAPNetWkstaGetInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op)
{
smb_user_t *uidp;
tp = p->parmsp + 1; /* Skip over function number */
- (void) smb_ParseString((unsigned char*) tp, (char **) &tp); /* skip over param descriptor */
- (void) smb_ParseString((unsigned char*) tp, (char **) &tp); /* skip over data descriptor */
+
+ {
+ char * cdescp;
+
+ cdescp = smb_ParseStringT2Parm(p, (unsigned char*) tp, (char **) &tp,
+ SMB_STRF_FORCEASCII);
+ if (strcmp(cdescp, "WrLh"))
+ return CM_ERROR_INVAL;
+ cdescp = smb_ParseStringT2Parm(p, (unsigned char*) tp, (char **) &tp,
+ SMB_STRF_FORCEASCII);
+ if (strcmp(cdescp, "zzzBBzz"))
+ return CM_ERROR_INVAL;
+ }
+
infoLevel = *tp++;
bufsize = *tp++;
return code;
}
+#pragma pack(push, 1)
+
typedef struct smb_rap_server_info_0 {
- char sv0_name[16];
+ BYTE sv0_name[16];
} smb_rap_server_info_0_t;
typedef struct smb_rap_server_info_1 {
- char sv1_name[16];
- char sv1_version_major;
- char sv1_version_minor;
- unsigned long sv1_type;
- DWORD *sv1_comment_or_master_browser; /* char *sv1_comment_or_master_browser;*/
+ BYTE sv1_name[16];
+ BYTE sv1_version_major;
+ BYTE sv1_version_minor;
+ DWORD sv1_type;
+ DWORD sv1_comment_or_master_browser; /* char *sv1_comment_or_master_browser;*/
} smb_rap_server_info_1_t;
+#pragma pack(pop)
+
char smb_ServerComment[] = "OpenAFS Client";
int smb_ServerCommentLen = sizeof(smb_ServerComment);
char * cstrp;
tp = p->parmsp + 1; /* Skip over function number */
- (void) smb_ParseString((unsigned char*) tp, (char **) &tp); /* skip over param descriptor */
- (void) smb_ParseString((unsigned char*) tp, (char **) &tp); /* skip over data descriptor */
+
+ {
+ char * cdescp;
+
+ cdescp = smb_ParseStringT2Parm(p, (unsigned char*) tp, (char **) &tp,
+ SMB_STRF_FORCEASCII);
+ if (strcmp(cdescp, "WrLh"))
+ return CM_ERROR_INVAL;
+ cdescp = smb_ParseStringT2Parm(p, (unsigned char*) tp, (char **) &tp,
+ SMB_STRF_FORCEASCII);
+ if (strcmp(cdescp, "B16") ||
+ strcmp(cdescp, "B16BBDz"))
+ return CM_ERROR_INVAL;
+ }
+
infoLevel = *tp++;
bufsize = *tp++;
info1->sv1_version_major = 5;
info1->sv1_version_minor = 1;
- info1->sv1_comment_or_master_browser = (DWORD *) (cstrp - outp->datap);
+ info1->sv1_comment_or_master_browser = (DWORD) (cstrp - outp->datap);
strcpy(cstrp, smb_ServerComment);
return code;
}
+/* SMB_COM_TRANSACTION2 and SMB_COM_TRANSACTION2_SECONDARY */
long smb_ReceiveV3Tran2A(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
smb_tran2Packet_t *asp;
return 0;
}
+/* TRANS2_OPEN2 */
long smb_ReceiveTran2Open(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op)
{
char *pathp;
if (attributes & SMB_ATTR_READONLY)
initialModeBits &= ~0222;
- pathp = (char *) (&p->parmsp[14]);
- if (smb_StoreAnsiFilenames)
- OemToChar(pathp,pathp);
+ pathp = smb_ParseStringT2Parm(p, (char *) (&p->parmsp[14]), NULL,
+ SMB_STRF_ANSIPATH);
outp = smb_GetTran2ResponsePacket(vcp, p, op, 40, 0);
return CM_ERROR_BAD_LEVEL;
}
+/* TRANS2_QUERY_FS_INFORMATION */
long smb_ReceiveTran2QFSInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op)
{
smb_tran2Packet_t *outp;
smb_tran2QFSInfo_t qi;
int responseSize;
- static char FSname[8] = {'A', 0, 'F', 0, 'S', 0, 0, 0};
+ size_t sz = 0;
osi_Log1(smb_logp, "T2 QFSInfo type 0x%x", p->parmsp[0]);
switch (p->parmsp[0]) {
case SMB_INFO_ALLOCATION:
+ /* alloc info */
responseSize = sizeof(qi.u.allocInfo);
- break;
- case SMB_INFO_VOLUME:
- responseSize = sizeof(qi.u.volumeInfo);
- break;
- case SMB_QUERY_FS_VOLUME_INFO:
- responseSize = sizeof(qi.u.FSvolumeInfo);
- break;
- case SMB_QUERY_FS_SIZE_INFO:
- responseSize = sizeof(qi.u.FSsizeInfo);
- break;
- case SMB_QUERY_FS_DEVICE_INFO:
- responseSize = sizeof(qi.u.FSdeviceInfo);
- break;
- case SMB_QUERY_FS_ATTRIBUTE_INFO:
- responseSize = sizeof(qi.u.FSattributeInfo);
- break;
- case SMB_INFO_UNIX: /* CIFS Unix Info */
- case SMB_INFO_MACOS: /* Mac FS Info */
- default:
- return CM_ERROR_BADOP;
- }
- outp = smb_GetTran2ResponsePacket(vcp, p, op, 0, responseSize);
- switch (p->parmsp[0]) {
- case SMB_INFO_ALLOCATION:
- /* alloc info */
qi.u.allocInfo.FSID = 0;
qi.u.allocInfo.sectorsPerAllocUnit = 1;
qi.u.allocInfo.totalAllocUnits = 0x7fffffff;
case SMB_INFO_VOLUME:
/* volume info */
- qi.u.volumeInfo.vsn = 1234;
- qi.u.volumeInfo.vnCount = 4;
+ qi.u.volumeInfo.vsn = 1234; /* Volume serial number */
+ qi.u.volumeInfo.vnCount = 4; /* Number of characters in label (AFS\0)*/
+
/* we're supposed to pad it out with zeroes to the end */
memset(&qi.u.volumeInfo.label, 0, sizeof(qi.u.volumeInfo.label));
- memcpy(qi.u.volumeInfo.label, "AFS", 4);
+ smb_UnparseString(op, qi.u.volumeInfo.label, "AFS", &sz, 0);
+
+ responseSize = sizeof(unsigned long) + sizeof(char) + max(12, sz);
break;
case SMB_QUERY_FS_VOLUME_INFO:
/* FS volume info */
- memset((char *)&qi.u.FSvolumeInfo.vct, 0, 4);
+ responseSize = sizeof(qi.u.FSvolumeInfo);
+
+ {
+ FILETIME ft = {0x832cf000, 0x01abfcc4}; /* October 1, 1982 00:00:00 +0600 */
+ memcpy(&qi.u.FSvolumeInfo.vct, &ft, sizeof(ft));
+ }
+
qi.u.FSvolumeInfo.vsn = 1234;
- qi.u.FSvolumeInfo.vnCount = 8;
- memcpy(qi.u.FSvolumeInfo.label, "A\0F\0S\0\0\0", 8);
+ qi.u.FSvolumeInfo.vnCount = 8; /* This is always in Unicode */
+ memcpy(qi.u.FSvolumeInfo.label, L"AFS", sizeof(L"AFS"));
break;
case SMB_QUERY_FS_SIZE_INFO:
/* FS size info */
+ responseSize = sizeof(qi.u.FSsizeInfo);
+
qi.u.FSsizeInfo.totalAllocUnits.HighPart = 0;
qi.u.FSsizeInfo.totalAllocUnits.LowPart= 0x7fffffff;
qi.u.FSsizeInfo.availAllocUnits.HighPart = 0;
case SMB_QUERY_FS_DEVICE_INFO:
/* FS device info */
+ responseSize = sizeof(qi.u.FSdeviceInfo);
+
qi.u.FSdeviceInfo.devType = 0x14; /* network file system */
qi.u.FSdeviceInfo.characteristics = 0x50; /* remote, virtual */
break;
case SMB_QUERY_FS_ATTRIBUTE_INFO:
/* FS attribute info */
+
/* attributes, defined in WINNT.H:
* FILE_CASE_SENSITIVE_SEARCH 0x1
* FILE_CASE_PRESERVED_NAMES 0x2
* despite our protestations to the contrary.
*/
qi.u.FSattributeInfo.attributes = 0x4003;
+ /* The maxCompLength is supposed to be in bytes */
+#ifdef SMB_UNICODE
+ if ((vcp->flags & SMB_VCFLAG_USEUNICODE) == SMB_VCFLAG_USEUNICODE)
+ qi.u.FSattributeInfo.maxCompLength = MAX_PATH * sizeof(wchar_t);
+ else {
+#endif
qi.u.FSattributeInfo.maxCompLength = MAX_PATH;
- qi.u.FSattributeInfo.FSnameLength = sizeof(FSname);
- memcpy(qi.u.FSattributeInfo.FSname, FSname, sizeof(FSname));
+#ifdef SMB_UNICODE
+ }
+#endif
+ smb_UnparseString(op, qi.u.FSattributeInfo.FSname, "AFS", &sz, 0);
+ qi.u.FSattributeInfo.FSnameLength = sz;
+
+ responseSize =
+ sizeof(qi.u.FSattributeInfo.attributes) +
+ sizeof(qi.u.FSattributeInfo.maxCompLength) +
+ sizeof(qi.u.FSattributeInfo.FSnameLength) +
+ sz;
+
break;
+
+ case SMB_INFO_UNIX: /* CIFS Unix Info */
+ case SMB_INFO_MACOS: /* Mac FS Info */
+ default:
+ return CM_ERROR_BADOP;
}
+ outp = smb_GetTran2ResponsePacket(vcp, p, op, 0, responseSize);
+
/* copy out return data, and set corresponding sizes */
outp->totalParms = 0;
outp->totalData = responseSize;
return code;
}
+/* TRANS2_QUERY_PATH_INFORMATION */
long smb_ReceiveTran2QPathInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *opx)
{
smb_tran2Packet_t *outp;
unsigned short attributes;
unsigned long extAttributes;
char shortName[13];
- unsigned int len;
+ size_t len;
cm_user_t *userp;
cm_space_t *spacep;
cm_scache_t *scp, *dscp;
return 0;
}
- pathp = (char *)(&p->parmsp[3]);
- if (smb_StoreAnsiFilenames)
- OemToChar(pathp,pathp);
+ 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));
lock_ConvertWToR(&scp->rw);
+ len = 0;
+
/* now we have the status in the cache entry, and everything is locked.
* Marshall the output data.
*/
if (infoLevel == SMB_QUERY_FILE_ALT_NAME_INFO) {
code = cm_GetShortName(pathp, userp, &req,
tidPathp, scp->fid.vnode, shortName,
- (size_t *) &len);
+ &len);
if (code) {
goto done;
}
- qpi.u.QPfileAltNameInfo.fileNameLength = (len + 1) * 2;
- mbstowcs((unsigned short *)qpi.u.QPfileAltNameInfo.fileName, shortName, len + 1);
+ smb_UnparseString(opx, qpi.u.QPfileAltNameInfo.fileName, shortName, &len, 0);
+ qpi.u.QPfileAltNameInfo.fileNameLength = len;
goto done;
}
else if (infoLevel == SMB_QUERY_FILE_NAME_INFO) {
- len = (unsigned int)strlen(lastComp);
- qpi.u.QPfileNameInfo.fileNameLength = (len + 1) * 2;
- mbstowcs((unsigned short *)qpi.u.QPfileNameInfo.fileName, lastComp, len + 1);
+ smb_UnparseString(opx, qpi.u.QPfileNameInfo.fileName, lastComp, &len, 0);
+ qpi.u.QPfileNameInfo.fileNameLength = len;
goto done;
}
qpi.u.QPfileAllInfo.currentByteOffset.LowPart = 0;
qpi.u.QPfileAllInfo.mode = 0;
qpi.u.QPfileAllInfo.alignmentRequirement = 0;
- len = (unsigned int)strlen(lastComp);
- qpi.u.QPfileAllInfo.fileNameLength = (len + 1) * 2;
- mbstowcs((unsigned short *)qpi.u.QPfileAllInfo.fileName, lastComp, len + 1);
+
+ smb_UnparseString(opx, qpi.u.QPfileAllInfo.fileName, lastComp, &len, 0);
+ qpi.u.QPfileAllInfo.fileNameLength = len;
}
/* send and free the packets */
return 0;
}
+/* TRANS2_SET_PATH_INFORMATION */
long smb_ReceiveTran2SetPathInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *opx)
{
#if 0
return 0;
}
- pathp = (char *)(&p->parmsp[3]);
- if (smb_StoreAnsiFilenames)
- OemToChar(pathp,pathp);
+ 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));
#endif
}
+/* TRANS2_QUERY_FILE_INFORMATION */
long smb_ReceiveTran2QFileInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *opx)
{
smb_tran2Packet_t *outp;
qfi.u.QFeaInfo.eaSize = 0;
}
else if (infoLevel == SMB_QUERY_FILE_NAME_INFO) {
- unsigned long len;
+ size_t len = 0;
char *name;
lock_ReleaseRead(&scp->rw);
else
name = "\\"; /* probably can't happen */
lock_ReleaseMutex(&fidp->mx);
- len = (unsigned long)strlen(name);
- outp->totalData = ((len+1)*2) + 4; /* this is actually what we want to return */
- qfi.u.QFfileNameInfo.fileNameLength = (len + 1) * 2;
- mbstowcs((unsigned short *)qfi.u.QFfileNameInfo.fileName, name, len + 1);
+
+ smb_UnparseString(opx, qfi.u.QFfileNameInfo.fileName, name, &len, 0);
+ outp->totalData = len + 4; /* this is actually what we want to return */
+ qfi.u.QFfileNameInfo.fileNameLength = len;
}
/* send and free the packets */
return 0;
}
+
+/* TRANS2_SET_FILE_INFORMATION */
long smb_ReceiveTran2SetFileInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *opx)
{
long code = 0;
return 0;
}
+/* TRANS2_FSCTL */
long
smb_ReceiveTran2FSCTL(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp)
{
return CM_ERROR_BADOP;
}
+/* TRANS2_IOCTL2 */
long
smb_ReceiveTran2IOCTL(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp)
{
return CM_ERROR_BADOP;
}
+/* TRANS2_FIND_NOTIFY_FIRST */
long
smb_ReceiveTran2FindNotifyFirst(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp)
{
return CM_ERROR_BADOP;
}
+/* TRANS2_FIND_NOTIFY_NEXT */
long
smb_ReceiveTran2FindNotifyNext(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp)
{
return CM_ERROR_BADOP;
}
+/* TRANS2_CREATE_DIRECTORY */
long
smb_ReceiveTran2CreateDirectory(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp)
{
return CM_ERROR_BADOP;
}
+/* TRANS2_SESSION_SETUP */
long
smb_ReceiveTran2SessionSetup(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp)
{
USHORT NetworkAddressOffset;
};
+/* TRANS2_GET_DFS_REFERRAL */
long
smb_ReceiveTran2GetDFSReferral(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op)
{
#endif /* DFS_SUPPORT */
}
+/* TRANS2_REPORT_DFS_INCONSISTENCY */
long
smb_ReceiveTran2ReportDFSInconsistency(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp)
{
long code = 0;
cm_scache_t *scp;
cm_scache_t *targetScp; /* target if scp is a symlink */
- char *dptr;
afs_uint32 dosTime;
FILETIME ft;
- int shortTemp;
unsigned short attr;
unsigned long lattr;
smb_dirListPatch_t *patchp;
if (mustFake || code) {
lock_ReleaseWrite(&scp->rw);
- dptr = patchp->dptr;
-
/* Plug in fake timestamps. A time stamp of 0 causes 'invalid parameter'
errors in the client. */
if (infoLevel >= SMB_FIND_FILE_DIRECTORY_INFO) {
+ smb_V3FileAttrsLong * fa = (smb_V3FileAttrsLong *) patchp->dptr;
+
/* 1969-12-31 23:59:59 +00 */
ft.dwHighDateTime = 0x19DB200;
ft.dwLowDateTime = 0x5BB78980;
/* copy to Creation Time */
- *((FILETIME *)dptr) = ft;
- dptr += 8;
-
- /* copy to Last Access Time */
- *((FILETIME *)dptr) = ft;
- dptr += 8;
-
- /* copy to Last Write Time */
- *((FILETIME *)dptr) = ft;
- dptr += 8;
-
- /* copy to Change Time */
- *((FILETIME *)dptr) = ft;
- dptr += 24;
+ fa->creationTime = ft;
+ fa->lastAccessTime = ft;
+ fa->lastWriteTime = ft;
+ fa->lastChangeTime = ft;
switch (scp->fileType) {
case CM_SCACHETYPE_DIRECTORY:
case CM_SCACHETYPE_MOUNTPOINT:
case CM_SCACHETYPE_SYMLINK:
case CM_SCACHETYPE_INVALID:
- *((u_long *)dptr) = SMB_ATTR_DIRECTORY;
+ fa->extFileAttributes = SMB_ATTR_DIRECTORY;
break;
default:
/* if we get here we either have a normal file
* and odd means it is to be treated as a file.
*/
if (mustFake && (scp->fid.vnode & 0x1))
- *((u_long *)dptr) = SMB_ATTR_DIRECTORY;
+ fa->extFileAttributes = SMB_ATTR_DIRECTORY;
else
- *((u_long *)dptr) = SMB_ATTR_NORMAL;
+ fa->extFileAttributes = SMB_ATTR_NORMAL;
}
/* merge in hidden attribute */
if ( patchp->flags & SMB_DIRLISTPATCH_DOTFILE ) {
- *((u_long *)dptr) |= SMB_ATTR_HIDDEN;
+ fa->extFileAttributes |= SMB_ATTR_HIDDEN;
}
- dptr += 4;
} else {
+ smb_V3FileAttrsShort * fa = (smb_V3FileAttrsShort *) patchp->dptr;
+
/* 1969-12-31 23:59:58 +00*/
dosTime = 0xEBBFBF7D;
- /* and copy out date */
- shortTemp = (dosTime>>16) & 0xffff;
- *((u_short *)dptr) = shortTemp;
- dptr += 2;
-
- /* copy out creation time */
- shortTemp = dosTime & 0xffff;
- *((u_short *)dptr) = shortTemp;
- dptr += 2;
-
- /* and copy out date */
- shortTemp = (dosTime>>16) & 0xffff;
- *((u_short *)dptr) = shortTemp;
- dptr += 2;
-
- /* copy out access time */
- shortTemp = dosTime & 0xffff;
- *((u_short *)dptr) = shortTemp;
- dptr += 2;
-
- /* and copy out date */
- shortTemp = (dosTime>>16) & 0xffff;
- *((u_short *)dptr) = shortTemp;
- dptr += 2;
-
- /* copy out mod time */
- shortTemp = dosTime & 0xffff;
- *((u_short *)dptr) = shortTemp;
- dptr += 10;
+ fa->creationDateTime = MAKELONG(HIWORD(dosTime),LOWORD(dosTime));
+ fa->lastAccessDateTime = fa->creationDateTime;
+ fa->lastWriteDateTime = fa->creationDateTime;
/* set the attribute */
switch (scp->fileType) {
case CM_SCACHETYPE_MOUNTPOINT:
case CM_SCACHETYPE_SYMLINK:
case CM_SCACHETYPE_INVALID:
- attr = SMB_ATTR_DIRECTORY;
+ fa->attributes = SMB_ATTR_DIRECTORY;
default:
- attr = SMB_ATTR_NORMAL;
+ fa->attributes = SMB_ATTR_NORMAL;
}
/* merge in hidden (dot file) attribute */
if ( patchp->flags & SMB_DIRLISTPATCH_DOTFILE ) {
- attr |= SMB_ATTR_HIDDEN;
+ fa->attributes |= SMB_ATTR_HIDDEN;
}
- *dptr++ = attr & 0xff;
- *dptr++ = (attr >> 8) & 0xff;
}
cm_ReleaseSCache(scp);
lock_ConvertWToR(&scp->rw);
- dptr = patchp->dptr;
-
if (infoLevel >= SMB_FIND_FILE_DIRECTORY_INFO) {
+ smb_V3FileAttrsLong * fa = (smb_V3FileAttrsLong *) patchp->dptr;
+
/* get filetime */
smb_LargeSearchTimeFromUnixTime(&ft, scp->clientModTime);
- /* copy to Creation Time */
- *((FILETIME *)dptr) = ft;
- dptr += 8;
-
- /* copy to Last Access Time */
- *((FILETIME *)dptr) = ft;
- dptr += 8;
-
- /* copy to Last Write Time */
- *((FILETIME *)dptr) = ft;
- dptr += 8;
-
- /* copy to Change Time */
- *((FILETIME *)dptr) = ft;
- dptr += 8;
+ fa->creationTime = ft;
+ fa->lastAccessTime = ft;
+ fa->lastWriteTime = ft;
+ fa->lastChangeTime = ft;
/* Use length for both file length and alloc length */
- *((LARGE_INTEGER *)dptr) = scp->length;
- dptr += 8;
- *((LARGE_INTEGER *)dptr) = scp->length;
- dptr += 8;
+ fa->endOfFile = scp->length;
+ fa->allocationSize = scp->length;
/* Copy attributes */
lattr = smb_ExtAttributes(scp);
else
lattr |= SMB_ATTR_HIDDEN;
}
- *((u_long *)dptr) = lattr;
- dptr += 4;
+
+ fa->extFileAttributes = lattr;
} else {
+ smb_V3FileAttrsShort * fa = (smb_V3FileAttrsShort *) patchp->dptr;
+
/* get dos time */
smb_SearchTimeFromUnixTime(&dosTime, scp->clientModTime);
- /* and copy out date */
- shortTemp = (dosTime>>16) & 0xffff;
- *((u_short *)dptr) = shortTemp;
- dptr += 2;
-
- /* copy out creation time */
- shortTemp = dosTime & 0xffff;
- *((u_short *)dptr) = shortTemp;
- dptr += 2;
-
- /* and copy out date */
- shortTemp = (dosTime>>16) & 0xffff;
- *((u_short *)dptr) = shortTemp;
- dptr += 2;
-
- /* copy out access time */
- shortTemp = dosTime & 0xffff;
- *((u_short *)dptr) = shortTemp;
- dptr += 2;
-
- /* and copy out date */
- shortTemp = (dosTime>>16) & 0xffff;
- *((u_short *)dptr) = shortTemp;
- dptr += 2;
-
- /* copy out mod time */
- shortTemp = dosTime & 0xffff;
- *((u_short *)dptr) = shortTemp;
- dptr += 2;
+ fa->creationDateTime = MAKELONG(HIWORD(dosTime), LOWORD(dosTime));
+ fa->lastAccessDateTime = fa->creationDateTime;
+ fa->lastWriteDateTime = fa->creationDateTime;
/* copy out file length and alloc length,
* using the same for both
*/
- *((u_long *)dptr) = scp->length.LowPart;
- dptr += 4;
- *((u_long *)dptr) = scp->length.LowPart;
- dptr += 4;
+ fa->dataSize = scp->length.LowPart;
+ fa->allocationSize = scp->length.LowPart;
/* finally copy out attributes as short */
attr = smb_Attributes(scp);
else
lattr |= SMB_ATTR_HIDDEN;
}
- *dptr++ = attr & 0xff;
- *dptr++ = (attr >> 8) & 0xff;
+ fa->attributes = attr;
}
lock_ReleaseRead(&scp->rw);
the usual mechanism.
This function will return either CM_ERROR_NOSUCHFILE or SUCCESS.
+
+ TRANS2_FIND_FIRST2 and TRANS2_FIND_NEXT2
*/
long smb_T2SearchDirSingle(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *opx)
{
int maxCount;
smb_dirListPatch_t *dirListPatchesp;
smb_dirListPatch_t *curPatchp;
- long orbytes; /* # of bytes in this output record */
- long ohbytes; /* # of bytes, except file name */
- long onbytes; /* # of bytes in name, incl. term. null */
+ size_t orbytes; /* # of bytes in this output record */
+ size_t ohbytes; /* # of bytes, except file name */
+ size_t onbytes; /* # of bytes in name, incl. term. null */
cm_scache_t *scp = NULL;
cm_scache_t *targetscp = NULL;
cm_user_t *userp = NULL;
char *op; /* output data ptr */
char *origOp; /* original value of op */
cm_space_t *spacep; /* for pathname buffer */
- long maxReturnData; /* max # of return data */
+ 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 */
cm_dirEntry_t * dep = NULL;
cm_req_t req;
char * s;
+ void * attrp = NULL;
+ smb_tran2Find_t * fp;
cm_InitReq(&req);
maxCount = p->parmsp[1];
infoLevel = p->parmsp[3];
searchFlags = p->parmsp[2];
- pathp = ((char *) p->parmsp) + 12; /* points to path */
+ pathp = smb_ParseStringT2Parm(p, (char *) &(p->parmsp[6]), NULL, SMB_STRF_ANSIPATH);
nextCookie = 0;
maskp = strrchr(pathp, '\\');
if (maskp == NULL)
switch ( infoLevel ) {
case SMB_INFO_STANDARD:
s = "InfoStandard";
+ ohbytes = sizeof(fp->u.FstandardInfo);
break;
+
case SMB_INFO_QUERY_EA_SIZE:
+ ohbytes = sizeof(fp->u.FeaSizeInfo);
s = "InfoQueryEaSize";
break;
+
case SMB_INFO_QUERY_EAS_FROM_LIST:
+ ohbytes = sizeof(fp->u.FeasFromListInfo);
s = "InfoQueryEasFromList";
break;
+
case SMB_FIND_FILE_DIRECTORY_INFO:
s = "FindFileDirectoryInfo";
+ ohbytes = sizeof(fp->u.FfileDirectoryInfo);
break;
+
case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
s = "FindFileFullDirectoryInfo";
+ ohbytes = sizeof(fp->u.FfileFullDirectoryInfo);
break;
+
case SMB_FIND_FILE_NAMES_INFO:
s = "FindFileNamesInfo";
+ ohbytes = sizeof(fp->u.FfileNamesInfo);
break;
+
case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
s = "FindFileBothDirectoryInfo";
+ ohbytes = sizeof(fp->u.FfileBothDirectoryInfo);
break;
+
default:
s = "unknownInfoLevel";
+ ohbytes = 0;
}
osi_Log1(smb_logp, "smb_T2SearchDirSingle info level: %s", s);
"smb_T2SearchDirSingle attr 0x%x, info level 0x%x, max count %d, flags 0x%x",
attribute, infoLevel, maxCount, searchFlags);
- if (infoLevel > SMB_FIND_FILE_BOTH_DIRECTORY_INFO) {
+ if (ohbytes == 0) {
osi_Log1(smb_logp, "Unsupported InfoLevel 0x%x", infoLevel);
return CM_ERROR_INVAL;
}
if (infoLevel >= SMB_FIND_FILE_DIRECTORY_INFO)
searchFlags &= ~TRAN2_FIND_FLAG_RETURN_RESUME_KEYS; /* no resume keys */
+ if (searchFlags & TRAN2_FIND_FLAG_RETURN_RESUME_KEYS)
+ ohbytes += 4;
+
dirListPatchesp = NULL;
maxReturnData = p->maxReturnData;
op += 4;
}
+ fp = (smb_tran2Find_t *) op;
+
if (infoLevel == SMB_FIND_FILE_BOTH_DIRECTORY_INFO
&& targetscp->fid.vnode != 0
&& !cm_Is8Dot3(maskp)) {
}
- /* Check if the name will fit */
- if (infoLevel < 0x101)
- ohbytes = 23; /* pre-NT */
- else if (infoLevel == SMB_FIND_FILE_NAMES_INFO)
- ohbytes = 12; /* NT names only */
- else
- ohbytes = 64; /* NT */
-
- if (infoLevel == SMB_FIND_FILE_BOTH_DIRECTORY_INFO)
- ohbytes += 26; /* Short name & length */
-
- if (searchFlags & TRAN2_FIND_FLAG_RETURN_RESUME_KEYS) {
- ohbytes += 4; /* if resume key required */
- }
-
- if (infoLevel != SMB_INFO_STANDARD
- && infoLevel != SMB_FIND_FILE_DIRECTORY_INFO
- && infoLevel != SMB_FIND_FILE_NAMES_INFO)
- ohbytes += 4; /* EASIZE */
-
/* add header to name & term. null */
- onbytes = (int)strlen(maskp);
- orbytes = ohbytes + onbytes + 1;
+ onbytes = 0;
+ smb_UnparseString(opx, NULL, maskp, &onbytes, SMB_STRF_ANSIPATH);
+ orbytes = ohbytes + onbytes;
/* now, we round up the record to a 4 byte alignment, and we make
* sure that we have enough room here for even the aligned version
* preceded by its length.
*/
/* First zero everything else */
- memset(origOp, 0, ohbytes);
+ memset(origOp, 0, orbytes);
- if (infoLevel <= SMB_FIND_FILE_DIRECTORY_INFO)
- *(origOp + ohbytes - 1) = (unsigned char) onbytes;
- else if (infoLevel == SMB_FIND_FILE_NAMES_INFO)
- *((u_long *)(op + 8)) = onbytes;
- else
- *((u_long *)(op + 60)) = onbytes;
- strcpy(origOp+ohbytes, maskp);
- if (smb_StoreAnsiFilenames)
- CharToOem(origOp+ohbytes, origOp+ohbytes);
+ onbytes = 0;
+ smb_UnparseString(opx, origOp + ohbytes, maskp, &onbytes, SMB_STRF_ANSIPATH);
- /* Short name if requested and needed */
- if (infoLevel == SMB_FIND_FILE_BOTH_DIRECTORY_INFO) {
+ switch (infoLevel) {
+ case SMB_INFO_STANDARD:
+ fp->u.FstandardInfo.fileNameLength = onbytes;
+ attrp = &fp->u.FstandardInfo.fileAttrs;
+ break;
+
+ case SMB_INFO_QUERY_EA_SIZE:
+ fp->u.FeaSizeInfo.fileNameLength = onbytes;
+ attrp = &fp->u.FeaSizeInfo.fileAttrs;
+ fp->u.FeaSizeInfo.eaSize = 0;
+ break;
+
+ case SMB_INFO_QUERY_EAS_FROM_LIST:
+ fp->u.FeasFromListInfo.fileNameLength = onbytes;
+ attrp = &fp->u.FeasFromListInfo.fileAttrs;
+ fp->u.FeasFromListInfo.eaSize = 0;
+ break;
+
+ case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
if (NeedShortName) {
- strcpy(op + 70, shortName);
- if (smb_StoreAnsiFilenames)
- CharToOem(op + 70, op + 70);
- *(op + 68) = (char)(shortNameEnd - shortName);
- }
+#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));
+ 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);
+#endif
}
+ /* Fallthrough */
+
+ case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
+ fp->u.FfileFullDirectoryInfo.eaSize = 0;
+ /* Fallthrough */
+
+ case SMB_FIND_FILE_DIRECTORY_INFO:
+ fp->u.FfileDirectoryInfo.nextEntryOffset = 0;
+ fp->u.FfileDirectoryInfo.fileIndex = 0;
+ attrp = &fp->u.FfileDirectoryInfo.fileAttrs;
+ fp->u.FfileDirectoryInfo.fileNameLength = onbytes;
+ break;
+
+ case SMB_FIND_FILE_NAMES_INFO:
+ fp->u.FfileNamesInfo.nextEntryOffset = 0;
+ fp->u.FfileNamesInfo.fileIndex = 0;
+ fp->u.FfileNamesInfo.fileNameLength = onbytes;
+ break;
- /* NextEntryOffset and FileIndex */
- if (infoLevel >= SMB_FIND_FILE_DIRECTORY_INFO) {
- int entryOffset = orbytes + align;
- *((u_long *)op) = 0;
- *((u_long *)(op+4)) = 0;
+ default:
+ /* we shouldn't hit this case */
+ osi_assertx(FALSE, "Unknown query type");
}
if (infoLevel != SMB_FIND_FILE_NAMES_INFO) {
+ osi_assert(attrp != NULL);
+
curPatchp = malloc(sizeof(*curPatchp));
osi_QAdd((osi_queue_t **) &dirListPatchesp,
&curPatchp->q);
- curPatchp->dptr = op;
- if (infoLevel >= SMB_FIND_FILE_DIRECTORY_INFO)
- curPatchp->dptr += 8;
+ curPatchp->dptr = attrp;
if (smb_hideDotFiles && smb_IsDotFile(maskp)) {
curPatchp->flags = SMB_DIRLISTPATCH_DOTFILE;
}
+/* TRANS2_FIND_FIRST2 and TRANS2_FIND_NEXT2 */
long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *opx)
{
int attribute;
smb_dirListPatch_t *curPatchp = 0;
cm_buf_t *bufferp;
long temp;
- long orbytes; /* # of bytes in this output record */
- long ohbytes; /* # of bytes, except file name */
- long onbytes; /* # of bytes in name, incl. term. null */
+ size_t orbytes; /* # of bytes in this output record */
+ size_t ohbytes; /* # of bytes, except file name */
+ size_t onbytes; /* # of bytes in name, incl. term. null */
osi_hyper_t dirLength;
osi_hyper_t bufferOffset;
osi_hyper_t curOffset;
char *op; /* output data ptr */
char *origOp; /* original value of op */
cm_space_t *spacep; /* for pathname buffer */
- long maxReturnData; /* max # of return data */
- long maxReturnParms; /* max # of return parms */
+ unsigned long maxReturnData; /* max # of return data */
+ unsigned long maxReturnParms; /* max # of return parms */
long bytesInBuffer; /* # data bytes in the output buffer */
int starPattern;
char *maskp; /* mask part of path */
int eos;
smb_tran2Packet_t *outp; /* response packet */
char *tidPathp;
- int align;
+ unsigned int align;
char shortName[13]; /* 8.3 name if needed */
int NeedShortName;
int foundInexact;
int fileType;
cm_fid_t fid;
cm_req_t req;
+ void * attrp;
char * s;
+ smb_tran2Find_t * fp;
cm_InitReq(&req);
maxCount = p->parmsp[1];
infoLevel = p->parmsp[3];
searchFlags = p->parmsp[2];
- pathp = ((char *) p->parmsp) + 12; /* points to path */
- if (smb_StoreAnsiFilenames)
- OemToChar(pathp,pathp);
+ pathp = smb_ParseStringT2Parm(p, (char *) (&p->parmsp[6]), NULL, SMB_STRF_ANSIPATH);
nextCookie = 0;
maskp = strrchr(pathp, '\\');
if (maskp == NULL)
return code;
}
}
-#endif
+#endif /* NOFINDFIRSTOPTIMIZE */
dir_enums++;
dsp = smb_NewDirSearch(1);
switch ( infoLevel ) {
case SMB_INFO_STANDARD:
s = "InfoStandard";
+ ohbytes = sizeof(fp->u.FstandardInfo);
break;
+
case SMB_INFO_QUERY_EA_SIZE:
+ ohbytes = sizeof(fp->u.FeaSizeInfo);
s = "InfoQueryEaSize";
break;
+
case SMB_INFO_QUERY_EAS_FROM_LIST:
+ ohbytes = sizeof(fp->u.FeasFromListInfo);
s = "InfoQueryEasFromList";
break;
+
case SMB_FIND_FILE_DIRECTORY_INFO:
s = "FindFileDirectoryInfo";
+ ohbytes = sizeof(fp->u.FfileDirectoryInfo);
break;
+
case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
s = "FindFileFullDirectoryInfo";
+ ohbytes = sizeof(fp->u.FfileFullDirectoryInfo);
break;
+
case SMB_FIND_FILE_NAMES_INFO:
s = "FindFileNamesInfo";
+ ohbytes = sizeof(fp->u.FfileNamesInfo);
break;
+
case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
s = "FindFileBothDirectoryInfo";
+ ohbytes = sizeof(fp->u.FfileBothDirectoryInfo);
break;
+
default:
s = "unknownInfoLevel";
+ ohbytes = 0;
}
osi_Log1(smb_logp, "T2 search dir info level: %s", s);
osi_Log3(smb_logp, "...T2 search op %d, id %d, nextCookie 0x%x",
p->opcode, dsp->cookie, nextCookie);
- if (infoLevel > SMB_FIND_FILE_BOTH_DIRECTORY_INFO) {
+ if (ohbytes == 0) {
osi_Log1(smb_logp, "Unsupported InfoLevel 0x%x", infoLevel);
smb_ReleaseDirSearch(dsp);
return CM_ERROR_INVAL;
if (infoLevel >= SMB_FIND_FILE_DIRECTORY_INFO)
searchFlags &= ~TRAN2_FIND_FLAG_RETURN_RESUME_KEYS; /* no resume keys */
+ if (searchFlags & TRAN2_FIND_FLAG_RETURN_RESUME_KEYS)
+ ohbytes += 4;
+
dirListPatchesp = NULL;
maxReturnData = p->maxReturnData;
/* skip over resume key */
op += 4;
+ fp = (smb_tran2Find_t *) op;
+
/* 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,
}
/* finally check if this name will fit */
-
- /* standard dir entry stuff */
- if (infoLevel < 0x101)
- ohbytes = 23; /* pre-NT */
- else if (infoLevel == SMB_FIND_FILE_NAMES_INFO)
- ohbytes = 12; /* NT names only */
- else
- ohbytes = 64; /* NT */
-
- if (infoLevel == SMB_FIND_FILE_BOTH_DIRECTORY_INFO)
- ohbytes += 26; /* Short name & length */
-
- if (searchFlags & TRAN2_FIND_FLAG_RETURN_RESUME_KEYS) {
- ohbytes += 4; /* if resume key required */
- }
-
- if ( infoLevel != SMB_INFO_STANDARD &&
- infoLevel != SMB_FIND_FILE_DIRECTORY_INFO &&
- infoLevel != SMB_FIND_FILE_NAMES_INFO)
- ohbytes += 4; /* EASIZE */
-
- /* add header to name & term. null */
- orbytes = onbytes + ohbytes + 1;
+ onbytes = 0;
+ smb_UnparseString(opx, NULL, dep->name, &onbytes, SMB_STRF_ANSIPATH);
+ orbytes = ohbytes + onbytes;
/* now, we round up the record to a 4 byte alignment,
* and we make sure that we have enough room here for
align = (4 - (orbytes & 3)) & 3;
else
align = 0;
+
if (orbytes + bytesInBuffer + align > maxReturnData) {
osi_Log1(smb_logp, "T2 dir search exceed max return data %d",
maxReturnData);
* Put out the name, preceded by its length.
*/
/* First zero everything else */
- memset(origOp, 0, ohbytes);
+ memset(origOp, 0, orbytes);
- if (infoLevel <= SMB_FIND_FILE_DIRECTORY_INFO)
- *(origOp + ohbytes - 1) = (unsigned char) onbytes;
- else if (infoLevel == SMB_FIND_FILE_NAMES_INFO)
- *((u_long *)(op + 8)) = onbytes;
- else
- *((u_long *)(op + 60)) = onbytes;
- strcpy(origOp+ohbytes, dep->name);
- if (smb_StoreAnsiFilenames)
- CharToOem(origOp+ohbytes, origOp+ohbytes);
+ onbytes = 0;
+ smb_UnparseString(opx, origOp + ohbytes, dep->name, &onbytes, SMB_STRF_ANSIPATH);
- /* Short name if requested and needed */
- if (infoLevel == SMB_FIND_FILE_BOTH_DIRECTORY_INFO) {
+ switch (infoLevel) {
+ case SMB_INFO_STANDARD:
+ fp->u.FstandardInfo.fileNameLength = onbytes;
+ attrp = &fp->u.FstandardInfo.fileAttrs;
+ break;
+
+ case SMB_INFO_QUERY_EA_SIZE:
+ fp->u.FeaSizeInfo.fileNameLength = onbytes;
+ attrp = &fp->u.FeaSizeInfo.fileAttrs;
+ fp->u.FeaSizeInfo.eaSize = 0;
+ break;
+
+ case SMB_INFO_QUERY_EAS_FROM_LIST:
+ fp->u.FeasFromListInfo.fileNameLength = onbytes;
+ attrp = &fp->u.FeasFromListInfo.fileAttrs;
+ fp->u.FeasFromListInfo.eaSize = 0;
+ break;
+
+ case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
if (NeedShortName) {
- strcpy(op + 70, shortName);
- if (smb_StoreAnsiFilenames)
- CharToOem(op + 70, op + 70);
- *(op + 68) = (char)(shortNameEnd - shortName);
+#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));
+ 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);
+#endif
}
+ /* Fallthrough */
+
+ case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
+ fp->u.FfileFullDirectoryInfo.eaSize = 0;
+ /* Fallthrough */
+
+ case SMB_FIND_FILE_DIRECTORY_INFO:
+ fp->u.FfileDirectoryInfo.nextEntryOffset = orbytes + align;
+ fp->u.FfileDirectoryInfo.fileIndex = nextEntryCookie;
+ attrp = &fp->u.FfileDirectoryInfo.fileAttrs;
+ fp->u.FfileDirectoryInfo.fileNameLength = onbytes;
+ break;
+
+ case SMB_FIND_FILE_NAMES_INFO:
+ fp->u.FfileNamesInfo.nextEntryOffset = orbytes + align;
+ fp->u.FfileNamesInfo.fileIndex = nextEntryCookie;
+ fp->u.FfileNamesInfo.fileNameLength = onbytes;
+ attrp = NULL;
+ break;
+
+ default:
+ /* we shouldn't hit this case */
+ osi_assertx(FALSE, "Unknown query type");
}
/* now, adjust the # of entries copied */
returnedNames++;
- /* NextEntryOffset and FileIndex */
- if (infoLevel >= SMB_FIND_FILE_DIRECTORY_INFO) {
- int entryOffset = orbytes + align;
- *((u_long *)op) = entryOffset;
- *((u_long *)(op+4)) = nextEntryCookie;
- }
-
/* now we emit the attribute. This is tricky, since
* we need to really stat the file to find out what
* type of entry we've got. Right now, we're copying
* safe to unlock the directory.
*/
if (infoLevel != SMB_FIND_FILE_NAMES_INFO) {
+ osi_assert(attrp != NULL);
curPatchp = malloc(sizeof(*curPatchp));
osi_QAdd((osi_queue_t **) &dirListPatchesp, &curPatchp->q);
- curPatchp->dptr = op;
- if (infoLevel >= SMB_FIND_FILE_DIRECTORY_INFO)
- curPatchp->dptr += 8;
+ curPatchp->dptr = attrp;
if (smb_hideDotFiles && smb_IsDotFile(dep->name)) {
curPatchp->flags = SMB_DIRLISTPATCH_DOTFILE;
- }
- else
+ } else {
curPatchp->flags = 0;
+ }
cm_SetFid(&curPatchp->fid, scp->fid.cell, scp->fid.volume, ntohl(dep->fid.vnode), ntohl(dep->fid.unique));
bytesInBuffer += orbytes;
/* and pad the record out */
- while (--align >= 0) {
+ while (align-- > 0) {
*origOp++ = 0;
bytesInBuffer++;
}
return 0;
}
+/* SMB_COM_FIND_CLOSE2 */
long smb_ReceiveV3FindClose(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
int dirHandle;
return 0;
}
+
+/* SMB_COM_FIND_NOTIFY_CLOSE */
long smb_ReceiveV3FindNotifyClose(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
smb_SetSMBDataLength(outp, 0);
return 0;
}
+/* SMB_COM_OPEN_ANDX */
long smb_ReceiveV3OpenX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
char *pathp;
smb_fid_t *fidp;
int attributes;
char *lastNamep;
- afs_uint32 dosTime;
+ unsigned long dosTime;
int openFun;
int trunc;
int openMode;
if (attributes & SMB_ATTR_READONLY)
initialModeBits &= ~0222;
- pathp = smb_GetSMBData(inp, NULL);
- if (smb_StoreAnsiFilenames)
- OemToChar(pathp,pathp);
+ pathp = smb_ParseASCIIBlock(inp, smb_GetSMBData(inp, NULL), NULL,
+ SMB_STRF_ANSIPATH);
spacep = inp->spacep;
smb_StripLastComponent(spacep->data, &lastNamep, pathp);
}
}
+/* SMB_COM_LOCKING_ANDX */
long smb_ReceiveV3LockingX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
cm_req_t req;
return code;
}
+/* SMB_COM_QUERY_INFORMATION2 */
long smb_ReceiveV3GetAttributes(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
unsigned short fid;
return code;
}
+/* SMB_COM_SET_INFORMATION2 */
long smb_ReceiveV3SetAttributes(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
unsigned short fid;
return code;
}
+/* SMB_COM_WRITE_ANDX */
long smb_ReceiveV3WriteX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
osi_hyper_t offset;
return code;
}
+/* SMB_COM_READ_ANDX */
long smb_ReceiveV3ReadX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
osi_hyper_t offset;
#define FILE_DELETE_ON_CLOSE 0x1000
#define FILE_OPEN_BY_FILE_ID 0x2000
+/* SMB_COM_NT_CREATE_ANDX */
long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
char *pathp, *realPathp;
if (extAttributes & SMB_ATTR_READONLY)
initialModeBits &= ~0222;
- pathp = smb_GetSMBData(inp, NULL);
+ if (nameLength == 0)
+ return CM_ERROR_INVAL;
+
+ pathp = smb_ParseStringCb(inp, smb_GetSMBData(inp, NULL), 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[nameLength] = 0;
- if (smb_StoreAnsiFilenames)
- OemToChar(realPathp,realPathp);
spacep = inp->spacep;
smb_StripLastComponent(spacep->data, &lastNamep, realPathp);
* A lot of stuff copied verbatim from NT Create&X to NT Tran Create.
* Instead, ultimately, would like to use a subroutine for common code.
*/
+
+/* 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;
initialModeBits &= ~0222;
pathp = parmp + (13 * sizeof(ULONG)) + sizeof(UCHAR);
+ pathp = smb_ParseStringCch(inp, pathp, 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[nameLength] = 0;
- if (smb_StoreAnsiFilenames)
- OemToChar(realPathp,realPathp);
-
spacep = cm_GetSpace();
smb_StripLastComponent(spacep->data, &lastNamep, realPathp);
return 0;
}
+/* NT_TRANSACT_NOTIFY_CHANGE (SMB_COM_NT_TRANSACT) */
long smb_ReceiveNTTranNotifyChange(smb_vc_t *vcp, smb_packet_t *inp,
smb_packet_t *outp)
{
/* "null SID" group SID */
};
+/* NT_TRANSACT_QUERY_SECURITY_DESC (SMB_COM_NT_TRANSACT) */
long smb_ReceiveNTTranQuerySecurityDesc(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
int parmOffset, parmCount, dataOffset, dataCount;
return CM_ERROR_BUFFERTOOSMALL;
}
+/* SMB_COM_NT_TRANSACT
+
+ SMB_COM_NT_TRANSACT_SECONDARY should also be handled here.
+ */
long smb_ReceiveNTTransact(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
unsigned short function;
((smb_t *)outp)->flg2 |= SMB_FLAGS2_IS_LONG_NAME;
switch (function) {
- case 1:
+ case 1: /* NT_TRANSACT_CREATE */
return smb_ReceiveNTTranCreate(vcp, inp, outp);
- case 2:
+ case 2: /* NT_TRANSACT_IOCTL */
osi_Log0(smb_logp, "SMB NT Transact Ioctl - not implemented");
break;
- case 3:
+ case 3: /* NT_TRANSACT_SET_SECURITY_DESC */
osi_Log0(smb_logp, "SMB NT Transact SetSecurityDesc - not implemented");
break;
- case 4:
+ case 4: /* NT_TRANSACT_NOTIFY_CHANGE */
return smb_ReceiveNTTranNotifyChange(vcp, inp, outp);
- case 5:
+ case 5: /* NT_TRANSACT_RENAME */
osi_Log0(smb_logp, "SMB NT Transact Rename - not implemented");
break;
- case 6:
+ case 6: /* NT_TRANSACT_QUERY_SECURITY_DESC */
return smb_ReceiveNTTranQuerySecurityDesc(vcp, inp, outp);
case 7:
osi_Log0(smb_logp, "SMB NT Transact Query Quota - not implemented");
lock_ReleaseMutex(&smb_Dir_Watch_Lock);
}
+/* SMB_COM_NT_CANCEL */
long smb_ReceiveNTCancel(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
unsigned char *replyWctp;
}
tp = smb_GetSMBData(inp, NULL);
- oldPathp = smb_ParseASCIIBlock(tp, &tp);
- if (smb_StoreAnsiFilenames)
- OemToChar(oldPathp,oldPathp);
- newPathp = smb_ParseASCIIBlock(tp, &tp);
- if (smb_StoreAnsiFilenames)
- OemToChar(newPathp,newPathp);
+ 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),
unsigned short res[6]; /* contains PidHigh */
unsigned short *parmsp; /* parms */
unsigned char *datap; /* data bytes */
+ cm_space_t * stringsp; /* decoded strings */
} smb_tran2Packet_t;
/* for flags field */
#define SMB_TRAN2PFLAG_ALLOC 1
+#define SMB_TRAN2PFLAG_USEUNICODE 2
typedef struct smb_tran2Dispatch {
long (*procp)(smb_vc_t *, smb_tran2Packet_t *, smb_packet_t *);
struct {
unsigned long vsn; /* volume serial number */
char vnCount; /* count of chars in label, incl null */
- char label[12]; /* pad out with nulls */
+ char /* STRING */ label[24]; /* pad out with nulls */
} volumeInfo;
struct {
FILETIME vct; /* volume creation time */
unsigned long vsn; /* volume serial number */
unsigned long vnCount; /* length of volume label in bytes */
char res[2]; /* reserved */
- char label[10]; /* volume label */
+ char /* STRING */ label[20]; /* volume label */
} FSvolumeInfo;
struct {
LARGE_INTEGER totalAllocUnits; /* on the disk */
unsigned long attributes;
unsigned long maxCompLength; /* max path component length */
unsigned long FSnameLength; /* length of file system name */
- unsigned char FSname[12];
+ unsigned char /* STRING */ FSname[24]; /* File system name */
} FSattributeInfo;
} u;
} smb_tran2QFSInfo_t;
} QPfileEaInfo;
struct {
unsigned long fileNameLength;
- unsigned char fileName[512];
+ unsigned char fileName[512]; /* STRING */
} QPfileNameInfo;
struct {
FILETIME creationTime;
unsigned long mode;
unsigned long alignmentRequirement;
unsigned long fileNameLength;
- unsigned char fileName[512];
+ unsigned char fileName[512]; /* STRING */
} QPfileAllInfo;
struct {
unsigned long fileNameLength;
- unsigned char fileName[512];
+ unsigned char fileName[512]; /* STRING */
} QPfileAltNameInfo;
struct {
unsigned long nextEntryOffset;
unsigned long streamNameLength;
LARGE_INTEGER streamSize;
LARGE_INTEGER streamAllocationSize;
- unsigned char fileName[512];
+ unsigned char fileName[512]; /* STRING */
} QPfileStreamInfo;
struct {
LARGE_INTEGER compressedFileSize;
} QFfileNameInfo;
} u;
} smb_tran2QFileInfo_t;
+
+typedef struct {
+ unsigned long creationDateTime; /* SMB_DATE / SMB_TIME */
+ unsigned long lastAccessDateTime; /* SMB_DATE / SMB_TIME */
+ unsigned long lastWriteDateTime; /* SMB_DATE / SMB_TIME */
+ unsigned long dataSize;
+ unsigned long allocationSize;
+ unsigned short attributes;
+} smb_V3FileAttrsShort;
+
+typedef struct {
+ FILETIME creationTime;
+ FILETIME lastAccessTime;
+ FILETIME lastWriteTime;
+ FILETIME lastChangeTime;
+ LARGE_INTEGER endOfFile;
+ LARGE_INTEGER allocationSize;
+ unsigned long extFileAttributes;
+} smb_V3FileAttrsLong;
+
+typedef struct {
+ union {
+ struct {
+ smb_V3FileAttrsShort fileAttrs;
+ unsigned char fileNameLength;
+ /* STRING fileName */
+ } FstandardInfo;
+
+ struct {
+ smb_V3FileAttrsShort fileAttrs;
+ unsigned long eaSize;
+ unsigned char fileNameLength;
+ /* STRING fileName */
+ } FeaSizeInfo, FeasFromListInfo;
+
+ struct {
+ unsigned long nextEntryOffset;
+ unsigned long fileIndex;
+ smb_V3FileAttrsLong fileAttrs;
+ unsigned long fileNameLength;
+ /* STRING fileName */
+ } FfileDirectoryInfo;
+
+ struct {
+ unsigned long nextEntryOffset;
+ unsigned long fileIndex;
+ smb_V3FileAttrsLong fileAttrs;
+ unsigned long fileNameLength;
+ unsigned long eaSize;
+ /* STRING fileName */
+ } FfileFullDirectoryInfo;
+
+ struct {
+ unsigned long nextEntryOffset;
+ unsigned long fileIndex;
+ smb_V3FileAttrsLong fileAttrs;
+ unsigned long fileNameLength;
+ unsigned long eaSize;
+ unsigned char shortNameLength;
+ unsigned char reserved;
+ wchar_t shortName[12];
+ /* STRING fileName */
+ } FfileBothDirectoryInfo;
+
+ struct {
+ unsigned long nextEntryOffset;
+ unsigned long fileIndex;
+ unsigned long fileNameLength;
+ /* STRING fileName */
+ } FfileNamesInfo;
+ } u;
+} smb_tran2Find_t;
+
#pragma pack(pop)
/* more than enough opcodes for today, anyway */
#define VIOC_UUIDCTL 0x30
#define VIOC_PATH_AVAILABILITY 0x31
#define VIOC_GETFILETYPE 0x32
+#define VIOC_UNICODECTL 0x33
#define VIOC_VOLSTAT_TEST 0x3F
/* Not to exceed SMB_IOCTL_MAXPROCS from smb_ioctl.h */
smb_ioctlProcsp[VIOC_PATH_AVAILABILITY] = cm_IoctlPathAvailability;
smb_ioctlProcsp[VIOC_GETFILETYPE] = cm_IoctlGetFileType;
smb_ioctlProcsp[VIOC_VOLSTAT_TEST] = cm_IoctlVolStatTest;
+ smb_ioctlProcsp[VIOC_UNICODECTL] = cm_IoctlUnicodeControl;
}
/* called to make a fid structure into an IOCTL fid structure */
blob.out_size = MAXSIZE;
blob.out = space;
- code = pioctl(apath, VIOC_FILE_CELL_NAME, &blob, 1);
+ code = pioctl_utf8(apath, VIOC_FILE_CELL_NAME, &blob, 1);
if (code) {
if ((errno == EINVAL) || (errno == ENOENT))
return 0;
blob.out_size = MAXSIZE;
blob.out = space;
- code = pioctl(apath, VIOC_FILE_CELL_NAME, &blob, 1);
+ code = pioctl_utf8(apath, VIOC_FILE_CELL_NAME, &blob, 1);
if (code == 0)
return !stricmp("Freelance.Local.Root",space);
return 1; /* assume it is because it is more restrictive that way */
blob.out = space;
memset(space, 0, MAXSIZE);
- code = pioctl(parent_dir, VIOC_LISTSYMLINK, &blob, 1);
+ code = pioctl_utf8(parent_dir, VIOC_LISTSYMLINK, &blob, 1);
if (code == 0)
printf("'%s' is a %ssymlink to '%s'\n",
return 1;
}
+ fprintf(stderr, "Creating symlink [%s] to [%s]\n", path, as->parms[1].items->data);
+
/* create symlink with a special pioctl for Windows NT, since it doesn't
* have a symlink system call.
*/
blob.in_size = 1 + (long)strlen(as->parms[1].items->data);
blob.in = as->parms[1].items->data;
blob.out = NULL;
- code = pioctl(path, VIOC_SYMLINK, &blob, 0);
+ code = pioctl_utf8(path, VIOC_SYMLINK, &blob, 0);
#else /* not WIN32 */
code = symlink(as->parms[1].items->data, path);
#endif /* not WIN32 */
blob.in_size = (int)strlen(tp)+1;
blob.out = lsbuffer;
blob.out_size = sizeof(lsbuffer);
- code = pioctl(tbuffer, VIOC_LISTSYMLINK, &blob, 0);
+ code = pioctl_utf8(tbuffer, VIOC_LISTSYMLINK, &blob, 0);
if (code) {
if (errno == EINVAL)
fprintf(stderr,"symlink: '%s' is not a symlink.\n", ti->data);
blob.out_size = 0;
blob.in = tp;
blob.in_size = (long)strlen(tp)+1;
- code = pioctl(tbuffer, VIOC_DELSYMLINK, &blob, 0);
+ code = pioctl_utf8(tbuffer, VIOC_DELSYMLINK, &blob, 0);
if (code) {
Die(errno, ti->data);
}
return code;
}
+static void
+FreeUtf8CmdLine(int argc, char ** argv)
+{
+ int i;
+ for (i=0; i < argc; i++) {
+ if (argv[i])
+ free(argv[i]);
+ }
+ free(argv);
+}
+
+static char **
+MakeUtf8Cmdline(int argc, const wchar_t **wargv)
+{
+ char ** argv;
+ int i;
+
+ argv = calloc(argc, sizeof(argv[0]));
+ if (argv == NULL)
+ return NULL;
+
+ for (i=0; i < argc; i++) {
+ int s;
+
+ s = WideCharToMultiByte(CP_UTF8, 0, wargv[i], -1, NULL, 0, NULL, FALSE);
+ if (s == 0 ||
+ (argv[i] = calloc(s+1, sizeof(char))) == NULL) {
+ break;
+ }
+
+ s = WideCharToMultiByte(CP_UTF8, 0, wargv[i], -1, argv[i], s+1, NULL, FALSE);
+ if (s == 0) {
+ break;
+ }
+ }
+
+ if (i < argc) {
+ FreeUtf8CmdLine(argc, argv);
+ return NULL;
+ }
+
+ return argv;
+}
+
static struct ViceIoctl gblob;
static int debug = 0;
-main(argc, argv)
-int argc;
-char **argv; {
+int wmain(int argc, wchar_t **wargv)
+{
register afs_int32 code;
register struct cmd_syndesc *ts;
+ char ** argv;
#ifdef AFS_AIX32_ENV
/*
/* try to find volume location information */
+ argv = MakeUtf8Cmdline(argc, wargv);
osi_Init();
if (rxInitDone) rx_Finalize();
#endif /* not WIN32 */
+ FreeUtf8CmdLine(argc, argv);
+
return code;
}
extern "C" {
#include "WINNT\afsreg.h"
}
+#define STRSAFE_NO_DEPRECATE
+#include <strsafe.h>
+
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
BOOL CAfsShlExt::InitInstance()
{
+ extern EXPORTED HINSTANCE TaLocale_LoadCorrespondingModuleByName (HINSTANCE hInstance, LPSTR pszFilename, WORD wSearchPriority = MODULE_PRIORITY_BOOSTED);
+
// Load our translated resources
- TaLocale_LoadCorrespondingModuleByName (m_hInstance, TEXT("afs_shl_ext.dll"));
+ TaLocale_LoadCorrespondingModuleByName (m_hInstance, "afs_shl_ext.dll");
// Register all OLE server (factories) as running. This enables the
// OLE libraries to create objects from other applications.
int WideCharToLocal(LPTSTR pLocal, LPCWSTR pWide, DWORD dwChars)
{
+#ifdef UNICODE
+ StringCchCopy(pLocal, dwChars, pWide);
+#else
*pLocal = 0;
WideCharToMultiByte( CP_ACP, 0, pWide, -1, pLocal, dwChars, NULL, NULL);
+#endif
return lstrlen(pLocal);
}
StringFromIID(IID_IShellExt, &pwsz);
if(pwsz)
{
+#ifdef UNICODE
+ StringCbCopy(szCLSID, sizeof(szCLSID), pwsz);
+#else
WideCharToMultiByte( CP_ACP, 0,pwsz, -1, szCLSID, sizeof(szCLSID), NULL, NULL);
- LPMALLOC pMalloc;
- CoGetMalloc(1, &pMalloc);
- if(pMalloc)
- {
- (pMalloc->Free)(pwsz);
- (pMalloc->Release)();
- }
+#endif
+ CoTaskMemFree(pwsz);
} else {
return E_FAIL;
}
@="Y:\\DEST\\root.client\\usr\\vice\\etc\\afs_shl_ext.dll"
"ThreadingModel"="Apartment"
*/
- HMODULE hModule=GetModuleHandle("afs_shl_ext.dll");
+ HMODULE hModule=GetModuleHandle(TEXT("afs_shl_ext.dll"));
DWORD z=GetModuleFileName(hModule,szModule,sizeof(szModule));
wsprintf(szSubKey, TEXT("CLSID\\%s\\InprocServer32"),szCLSID);
if ((lResult=DoRegCLSID(HKEY_CLASSES_ROOT,szSubKey,szModule))!=NOERROR)
return lResult;
wsprintf(szSubKey, TEXT("CLSID\\%s\\InprocServer32"),szCLSID);
- if ((lResult=DoRegCLSID(HKEY_CLASSES_ROOT,szSubKey,"Apartment","ThreadingModel"))!=NOERROR)
+ if ((lResult=DoRegCLSID(HKEY_CLASSES_ROOT,szSubKey,
+ TEXT("Apartment"),TEXT("ThreadingModel")))!=NOERROR)
return lResult;
/*
if(VER_PLATFORM_WIN32_NT == osvi.dwPlatformId)
{
wsprintf(szSubKey, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved"));
- if ((lResult=DoRegCLSID(HKEY_LOCAL_MACHINE,szSubKey,STR_EXT_TITLE,szCLSID))!=NOERROR)
+ if ((lResult=DoRegCLSID(HKEY_LOCAL_MACHINE,szSubKey,_TEXT(STR_EXT_TITLE),szCLSID))!=NOERROR)
return lResult;
}
wsprintf(szSubKey, TEXT("*\\shellex\\ContextMenuHandlers\\%s"),STR_EXT_TITLE);
TCHAR szData[MAX_PATH];
//Create the value string.
- lstrcpy(szData, STR_EXT_TITLE);
+ lstrcpy(szData, _TEXT(STR_EXT_TITLE));
lResult = RegSetValueEx( hKey,
szCLSID,
StringFromIID(IID_IShellExt, &pwsz);
if(pwsz)
{
+#ifdef UNICODE
+ StringCbCopy(szCLSID, sizeof(szCLSID), pwsz);
+#else
WideCharToMultiByte( CP_ACP, 0,pwsz, -1, szCLSID, sizeof(szCLSID), NULL, NULL);
- LPMALLOC pMalloc;
- CoGetMalloc(1, &pMalloc);
- if(pMalloc)
- {
- (pMalloc->Free)(pwsz);
- (pMalloc->Release)();
- }
+#endif
+ CoTaskMemFree(pwsz);
} else {
return E_FAIL;
}
*/
#include "stdafx.h"
+#include <shlwapi.h>
#include <winsock2.h>
#include <ws2tcpip.h>
m_bClear = m_Clear.GetCheck() == 1;
m_ToDir.GetWindowText(m_strToDir);
- if (access(m_strToDir, 0) == -1) {
+ if (PathIsDirectory(m_strToDir) == -1) {
ShowMessageBox(IDS_DIR_DOES_NOT_EXIST_ERROR, MB_ICONEXCLAMATION, IDS_DIR_DOES_NOT_EXIST_ERROR, m_strToDir);
return;
}
void CCopyAclDlg::OnBrowse()
{
- CFileDialog dlg(TRUE, 0, "*.*", OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_NOCHANGEDIR | OFN_HIDEREADONLY, 0, 0);
+ CFileDialog dlg(TRUE, 0, TEXT("*.*"), OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_NOCHANGEDIR | OFN_HIDEREADONLY, 0, 0);
if (dlg.DoModal() == IDCANCEL)
return;
#include <cm.h>
}
+#define STRSAFE_NO_DEPRECATE
+#include <strsafe.h>
+
#define PCCHAR(str) ((char *)(const char *)(str))
#define VL_NOENT (363524L)
static char *szLogFileName = "afsguilog.txt";
#endif
+#ifdef UNICODE
+class CStringUtf8 : public CStringA
+{
+public:
+ CStringUtf8(const CStringW& csw) : CStringA()
+ {
+ SetString(csw);
+ }
+
+ CStringUtf8(const char * cp) : CStringA(cp) {}
+
+ CStringUtf8() :CStringA() {}
+
+ void SetString(const CStringW& csw)
+ {
+ char buffer[1024];
+ int rv;
+
+ rv = WideCharToMultiByte(CP_UTF8, 0, csw, -1,
+ buffer, sizeof(buffer),
+ NULL, FALSE);
+
+ if (rv != 0) {
+ CStringA::SetString(buffer);
+ } else {
+ if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
+ int cb_req;
+
+ cb_req = WideCharToMultiByte(CP_UTF8, 0, csw, -1, NULL, 0, NULL, FALSE);
+ if (cb_req != 0) {
+ cb_req ++;
+
+ WideCharToMultiByte(CP_UTF8, 0, csw, -1, CStringA::GetBuffer(cb_req), cb_req, NULL, FALSE);
+ CStringA::ReleaseBuffer();
+ }
+ } else {
+#ifdef DEBUG
+ DebugBreak();
+#endif
+ }
+ }
+ }
+
+ static CString _Utf8ToCString(const char * ustr)
+ {
+ CString cs;
+ int cch;
+
+ cch = MultiByteToWideChar(CP_UTF8, 0, ustr, -1, NULL, 0);
+ if (cch == 0) {
+ cs.Empty();
+ return cs;
+ }
+
+ cch++;
+ cch = MultiByteToWideChar(CP_UTF8, 0, ustr, -1, cs.GetBuffer(cch), cch);
+ cs.ReleaseBuffer();
+
+ return cs;
+ }
+};
+
+long pioctl_T(const CString& path, long opcode, struct ViceIoctl * blob, int follow)
+{
+ CStringUtf8 upath(path);
+
+ return pioctl_utf8(PCCHAR(upath), opcode, blob, follow);
+}
+
+#define Utf8ToCString(cs) CStringUtf8::_Utf8ToCString(cs)
+#else
+#define pioctl_T(path, op, vblob, follow) pioctl(PCCHAR(path), op, vblob, follow)
+#define Utf8ToCString(cs) (cs)
+#endif
+
+
+
static int
VLDBInit(int noAuthFlag, struct afsconf_cell *info)
{
return code;
}
-FILE *OpenFile(char *file, char *rwp)
+static FILE *
+OpenFile(char *file, char *rwp)
{
char wdir[256];
long code;
long tlen;
FILE *fp;
- code = GetWindowsDirectory(wdir, sizeof(wdir));
+ code = GetWindowsDirectoryA(wdir, sizeof(wdir));
if (code == 0 || code > sizeof(wdir))
return FALSE;
for (int i = 0; i < files.GetSize(); i++) {
blob.in_size = blob.out_size = 0;
- code = pioctl(PCCHAR(files[i]), VIOCFLUSH, &blob, 0);
+ code = pioctl_T(files[i], VIOCFLUSH, &blob, 0);
if (code) {
error = 1;
if (errno == EMFILE)
for (int i = 0; i < files.GetSize(); i++) {
blob.in_size = blob.out_size = 0;
- code = pioctl(PCCHAR(files[i]), VIOC_FLUSHVOLUME, &blob, 0);
+ code = pioctl_T(files[i], VIOC_FLUSHVOLUME, &blob, 0);
if (code) {
error = 1;
ShowMessageBox(IDS_FLUSH_VOLUME_ERROR, MB_ICONERROR, IDS_FLUSH_VOLUME_ERROR, files[i], strerror(errno));
blob.out_size = MAXSIZE;
blob.out = space;
- code = pioctl(PCCHAR(files[i]), VIOC_FILE_CELL_NAME, &blob, 1);
+ code = pioctl_T(files[i], VIOC_FILE_CELL_NAME, &blob, 1);
if (code) {
if (code == ENOENT) {
LoadString (str, IDS_CANT_GET_CELL);
results.Add(str);
} else
results.Add(GetAfsError(errno));
- } else
- results.Add(space);
+ } else {
+ results.Add(Utf8ToCString(space));
+ }
}
LoadString (str, IDS_SHOW_CELL);
blob.out = space;
memset(space, 0, sizeof(space));
- code = pioctl(PCCHAR(files[i]), VIOCWHEREIS, &blob, 1);
+ code = pioctl_T(files[i], VIOCWHEREIS, &blob, 1);
if (code) {
resultFiles.Add(StripPath(files[i]));
servers.Add(GetAfsError(errno));
}
}
-CString GetAfsError(int code, const char *filename)
+CString GetAfsError(int code, const TCHAR *filename)
{
CString strMsg;
if (code == EINVAL) {
if (filename)
- strMsg.Format("Invalid argument; it is possible that the file is not in AFS");
+ strMsg.Format(_T("Invalid argument; it is possible that the file is not in AFS"));
else
- strMsg.Format("Invalid argument");
+ strMsg.Format(_T("Invalid argument"));
} else if (code == ENOENT) {
if (filename)
- strMsg.Format("The file does not exist");
+ strMsg.Format(_T("The file does not exist"));
else
- strMsg.Format("No such file returned");
+ strMsg.Format(_T("No such file returned"));
} else if (code == EROFS) {
- strMsg.Format("You can not change a backup or readonly volume");
+ strMsg.Format(_T("You can not change a backup or readonly volume"));
} else if (code == EACCES || code == EPERM) {
- strMsg.Format("You do not have the required rights to do this operation");
+ strMsg.Format(_T("You do not have the required rights to do this operation"));
} else if (code == ENODEV) {
- strMsg.Format("AFS service may not have started");
+ strMsg.Format(_T("AFS service may not have started"));
} else if (code == ESRCH) {
- strMsg.Format("Cell name not recognized");
+ strMsg.Format(_T("Cell name not recognized"));
} else if (code == ETIMEDOUT) {
- strMsg.Format("Connection timed out");
+ strMsg.Format(_T("Connection timed out"));
} else if (code == EPIPE) {
- strMsg.Format("Volume name or ID not recognized");
+ strMsg.Format(_T("Volume name or ID not recognized"));
} else {
- strMsg.Format("Error 0x%x occurred", code);
+ strMsg.Format(_T("Error 0x%x occurred"), code);
}
return strMsg;
CString str;
if (!dfs) {
- if (arights & PRSFS_READ) str += "r";
- if (arights & PRSFS_LOOKUP) str += "l";
- if (arights & PRSFS_INSERT) str += "i";
- if (arights & PRSFS_DELETE) str += "d";
- if (arights & PRSFS_WRITE) str += "w";
- if (arights & PRSFS_LOCK) str += "k";
- if (arights & PRSFS_ADMINISTER) str += "a";
+ if (arights & PRSFS_READ) str += _T("r");
+ if (arights & PRSFS_LOOKUP) str += _T("l");
+ if (arights & PRSFS_INSERT) str += _T("i");
+ if (arights & PRSFS_DELETE) str += _T("d");
+ if (arights & PRSFS_WRITE) str += _T("w");
+ if (arights & PRSFS_LOCK) str += _T("k");
+ if (arights & PRSFS_ADMINISTER) str += _T("a");
} else {
ASSERT(FALSE);
/*
- if (arights & DFS_READ) str += "r"; else str += "-";
- if (arights & DFS_WRITE) str += "w"; else printf("-");
- if (arights & DFS_EXECUTE) str += "x"; else printf("-");
- if (arights & DFS_CONTROL) str += "c"; else printf("-");
- if (arights & DFS_INSERT) str += "i"; else printf("-");
- if (arights & DFS_DELETE) str += "d"; else printf("-");
- if (arights & (DFS_USRALL)) str += "+";
+ if (arights & DFS_READ) str += _T("r"); else str += _T("-");
+ if (arights & DFS_WRITE) str += _T("w"); else printf(_T("-"));
+ if (arights & DFS_EXECUTE) str += _T("x"); else printf(_T("-"));
+ if (arights & DFS_CONTROL) str += _T("c"); else printf(_T("-"));
+ if (arights & DFS_INSERT) str += _T("i"); else printf(_T("-"));
+ if (arights & DFS_DELETE) str += _T("d"); else printf(_T("-"));
+ if (arights & (DFS_USRALL)) str += _T("+");
*/
}
struct Acl *EmptyAcl(const CString& strCellName)
{
register struct Acl *tp;
+ CStringUtf8 ustrCell(strCellName);
tp = (struct Acl *)malloc(sizeof (struct Acl));
tp->nplus = tp->nminus = 0;
tp->pluslist = tp->minuslist = 0;
tp->dfs = 0;
- strcpy(tp->cell, strCellName);
+ StringCbCopyA(tp->cell, sizeof(tp->cell), ustrCell);
return tp;
}
}
ta->minuslist = first;
- exit:
return ta;
nminus_err:
blob.in_size = 0;
blob.out = space;
- code = pioctl(PCCHAR(names[i]), VIOCGETAL, &blob, 1);
+ code = pioctl_T(names[i], VIOCGETAL, &blob, 1);
if (code) {
ShowMessageBox(IDS_CLEANACL_ERROR, MB_ICONERROR, 0, names[i], GetAfsError(errno));
continue;
blob.in_size = strlen((char *)blob.in) + 1;
blob.out_size = 0;
- code = pioctl(PCCHAR(names[i]), VIOCSETAL, &blob, 1);
+ code = pioctl_T(names[i], VIOCSETAL, &blob, 1);
if (code) {
if (errno == EINVAL) {
ShowMessageBox(IDS_CLEANACL_INVALID_ARG, MB_ICONERROR, IDS_CLEANACL_INVALID_ARG, names[i]);
blob.in_size = idf;
blob.in = blob.out = space;
- code = pioctl(PCCHAR(strDir), VIOCGETAL, &blob, 1);
+ code = pioctl_T(strDir, VIOCGETAL, &blob, 1);
if (code) {
ShowMessageBox(IDS_GETRIGHTS_ERROR, MB_ICONERROR, IDS_GETRIGHTS_ERROR, strDir, GetAfsError(errno));
return FALSE;
return 0;
}
-void ChangeList (struct Acl *pAcl, BYTE bNormalRights, const char *entryName, LONG nEntryRights)
+void ChangeList(struct Acl *pAcl, BYTE bNormalRights, const CString & entryName, LONG nEntryRights)
{
ASSERT(pAcl);
ASSERT(entryName);
struct AclEntry *pEntry;
+ CStringUtf8 uEntryName(entryName);
HOURGLASS hourglass;
pEntry = (bNormalRights ? pAcl->pluslist : pAcl->minuslist);
- pEntry = FindList(pEntry, entryName);
+ pEntry = FindList(pEntry, uEntryName);
/* Found the item already in the list. */
if (pEntry) {
pEntry = (struct AclEntry *) malloc(sizeof (struct AclEntry));
ASSERT(pEntry);
- strcpy(pEntry->name, entryName);
+ strcpy(pEntry->name, uEntryName);
pEntry->rights = nEntryRights;
if (bNormalRights) {
enum rtype {add, destroy, deny};
-LONG Convert(const register char *arights, int dfs, enum rtype *rtypep)
+static LONG Convert(const CString& strRights, int dfs, enum rtype *rtypep)
{
register int i, len;
LONG mode;
- register char tc;
*rtypep = add; /* add rights, by default */
- if (!strcmp(arights,"read"))
+ if (strRights == _T("read"))
return PRSFS_READ | PRSFS_LOOKUP;
- if (!strcmp(arights, "write"))
+ if (strRights == _T("write"))
return PRSFS_READ | PRSFS_LOOKUP | PRSFS_INSERT | PRSFS_DELETE | PRSFS_WRITE | PRSFS_LOCK;
- if (!strcmp(arights, "mail"))
+ if (strRights == _T("mail"))
return PRSFS_INSERT | PRSFS_LOCK | PRSFS_LOOKUP;
- if (!strcmp(arights, "all"))
+ if (strRights == _T("all"))
return PRSFS_READ | PRSFS_LOOKUP | PRSFS_INSERT | PRSFS_DELETE | PRSFS_WRITE | PRSFS_LOCK | PRSFS_ADMINISTER;
- if (!strcmp(arights, "none")) {
+ if (strRights == _T("none")) {
*rtypep = destroy; /* Remove entire entry */
return 0;
}
- len = strlen(arights);
+ len = strRights.GetLength();
mode = 0;
for (i = 0; i < len; i++) {
- tc = *arights++;
- if (tc == 'r') mode |= PRSFS_READ;
- else if (tc == 'l') mode |= PRSFS_LOOKUP;
- else if (tc == 'i') mode |= PRSFS_INSERT;
- else if (tc == 'd') mode |= PRSFS_DELETE;
- else if (tc == 'w') mode |= PRSFS_WRITE;
- else if (tc == 'k') mode |= PRSFS_LOCK;
- else if (tc == 'a') mode |= PRSFS_ADMINISTER;
+ TCHAR c = strRights[i];
+ if (c == _T('r')) mode |= PRSFS_READ;
+ else if (c == _T('l')) mode |= PRSFS_LOOKUP;
+ else if (c == _T('i')) mode |= PRSFS_INSERT;
+ else if (c == _T('d')) mode |= PRSFS_DELETE;
+ else if (c == _T('w')) mode |= PRSFS_WRITE;
+ else if (c == _T('k')) mode |= PRSFS_LOCK;
+ else if (c == _T('a')) mode |= PRSFS_ADMINISTER;
else {
- fprintf(stderr, "illegal rights character '%c'.\n", tc);
+ fprintf(stderr, "illegal rights character '%c'.\n", c);
exit(1);
}
}
blob.out_size = 0;
blob.in_size = 1 + strlen((const char *)blob.in);
- code = pioctl(PCCHAR(strDir), VIOCSETAL, &blob, 1);
+ code = pioctl_T(strDir, VIOCSETAL, &blob, 1);
if (code) {
if (errno == EINVAL)
ShowMessageBox(IDS_SAVE_ACL_EINVAL_ERROR, MB_ICONERROR, IDS_SAVE_ACL_EINVAL_ERROR, strDir);
blob.in_size = idf;
blob.in = blob.out = space;
- code = pioctl(PCCHAR(strToDir), VIOCGETAL, &blob, 1);
+ code = pioctl_T(strToDir, VIOCGETAL, &blob, 1);
if (code) {
ShowMessageBox(IDS_ACL_READ_ERROR, MB_ICONERROR, IDS_ACL_READ_ERROR, strToDir, GetAfsError(errno, strToDir));
return FALSE;
blob.out_size = 0;
blob.in_size = 1 + strlen((char *)blob.in);
- code = pioctl(PCCHAR(strToDir), VIOCSETAL, &blob, 1);
+ code = pioctl_T(strToDir, VIOCSETAL, &blob, 1);
if (code) {
ZapAcl(pToAcl);
if (errno == EINVAL)
} else
strVolume = strMountPoint.Mid(1);
- strMountPointInfo = strFile + "\t" + strVolume + "\t" + strCell + "\t" + strType;
+ strMountPointInfo = strFile + _T("\t") + strVolume + _T("\t") + strCell + _T("\t") + strType;
return strMountPointInfo;
}
{
CString strSymlinkInfo;
- strSymlinkInfo = strFile + "\t" + strSymlink;
+ strSymlinkInfo = strFile + _T("\t") + strSymlink;
return strSymlinkInfo;
}
-BOOL IsPathInAfs(const CHAR *strPath)
+BOOL IsPathInAfs(const CString & strPath)
{
struct ViceIoctl blob;
int code;
HOURGLASS hourglass;
- char buf[512];
- sprintf(buf, "IsPathInAfs(%s)", strPath);
- OutputDebugString(buf);
+ CString debugBuf;
+
+ debugBuf.Format(_T("IsPathInAfs(%s)"), strPath);
+ OutputDebugString(debugBuf);
blob.in_size = 0;
blob.out_size = MAXSIZE;
blob.out = space;
- code = pioctl((LPTSTR)((LPCTSTR)strPath), VIOC_FILE_CELL_NAME, &blob, 1);
+ code = pioctl_T(strPath, VIOC_FILE_CELL_NAME, &blob, 1);
- sprintf(buf, "VIOC_FILE_CELL_NAME=%d", code);
- OutputDebugString(buf);
+ debugBuf.Format(_T("VIOC_FILE_CELL_NAME=%d"), code);
+ OutputDebugString(debugBuf);
if (code) {
if ((errno == EINVAL) || (errno == ENOENT))
}
static int
-IsFreelanceRoot(char *apath)
+IsFreelanceRoot(const CString& apath)
{
struct ViceIoctl blob;
afs_int32 code;
blob.out_size = MAXSIZE;
blob.out = space;
- code = pioctl(apath, VIOC_FILE_CELL_NAME, &blob, 1);
+ code = pioctl_T(apath, VIOC_FILE_CELL_NAME, &blob, 1);
if (code == 0)
return !strcmp("Freelance.Local.Root",space);
return 1; /* assume it is because it is more restrictive that way */
}
-const char * NetbiosName(void)
+static const char * NetbiosName(void)
{
static char buffer[1024] = "AFS";
HKEY parmKey;
DWORD dummyLen;
DWORD enabled = 0;
- code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
+ code = RegOpenKeyExA(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
0, (IsWow64()?KEY_WOW64_64KEY:0)|KEY_QUERY_VALUE, &parmKey);
if (code == ERROR_SUCCESS) {
dummyLen = sizeof(buffer);
- code = RegQueryValueEx(parmKey, "NetbiosName", NULL, NULL,
+ code = RegQueryValueExA(parmKey, "NetbiosName", NULL, NULL,
(LPBYTE)buffer, &dummyLen);
RegCloseKey (parmKey);
} else {
return buffer;
}
+static void FixNetbiosPath(CString& path)
+{
+ if (!IsPathInAfs(path)) {
+ CString nbroot;
+ const char * nbname = NetbiosName();
+
+#ifdef UNICODE
+ nbroot.Format(_T("\\\\%S\\"), nbname);
+#else
+ nbroot.Format(_T("\\\\%s\\"), nbname);
+#endif
+
+ if (nbroot.CompareNoCase(path) == 0) {
+ path.Append(_T("all\\"));
+ }
+ }
+}
+
#define AFSCLIENT_ADMIN_GROUPNAME "AFS Client Admins"
static BOOL IsAdmin (void)
*/
PSID psidAdmin = NULL;
DWORD dwSize, dwSize2;
- char pszAdminGroup[ MAX_COMPUTERNAME_LENGTH + sizeof(AFSCLIENT_ADMIN_GROUPNAME) + 2 ];
- char *pszRefDomain = NULL;
+ TCHAR pszAdminGroup[ MAX_COMPUTERNAME_LENGTH + sizeof(AFSCLIENT_ADMIN_GROUPNAME) + 2 ];
+ TCHAR *pszRefDomain = NULL;
SID_NAME_USE snu = SidTypeGroup;
dwSize = sizeof(pszAdminGroup);
dwSize = 0;
dwSize2 = 0;
- strcat(pszAdminGroup,"\\");
- strcat(pszAdminGroup, AFSCLIENT_ADMIN_GROUPNAME);
+ lstrcat(pszAdminGroup, _T("\\"));
+ lstrcat(pszAdminGroup, _T(AFSCLIENT_ADMIN_GROUPNAME));
LookupAccountName(NULL, pszAdminGroup, NULL, &dwSize, NULL, &dwSize2, &snu);
/* that should always fail. */
}
psidAdmin = (PSID)malloc(dwSize); memset(psidAdmin,0,dwSize);
- pszRefDomain = (char *)malloc(dwSize2);
+ pszRefDomain = (TCHAR *)malloc(dwSize2);
if (!LookupAccountName(NULL, pszAdminGroup, psidAdmin, &dwSize, pszRefDomain, &dwSize2, &snu)) {
/* We can't lookup the group now even though we looked it up earlier.
return fAdmin;
}
-/* return a static pointer to a buffer */
-static char *Parent(char *apath)
+CString Parent(const CString& path)
{
- register char *tp;
+ int last_slash = path.ReverseFind(_T('\\'));
- strcpy(tspace, apath);
- tp = strrchr(tspace, '\\');
- if (tp) {
- *(tp+1) = 0; /* lv trailing slash so Parent("k:\foo") is "k:\" not "k:" */
+ if (last_slash != -1) {
+ CString ret = path.Left(last_slash + 1);
+ return ret;
+ } else {
+ if (path.GetLength() >= 2 && path[1] == _T(':')) {
+ CString ret = path.Left(2);
+ ret.AppendChar(_T('.'));
+ return ret;
+ } else {
+ CString ret = _T(".");
+ return ret;
+ }
}
- else {
- fs_ExtractDriveLetter(apath, tspace);
- strcat(tspace, ".");
}
- return tspace;
+CString LastComponent(const CString& path)
+{
+ int last_slash = path.ReverseFind(_T('\\'));
+
+ if (last_slash != -1) {
+ CString ret = path.Mid(last_slash + 1);
+ return ret;
+ } else {
+ if (path.GetLength() >= 2 && path[1] == _T(':')) {
+ CString ret = path.Mid(2);
+ return ret;
+ } else {
+ CString ret = path;
+ return ret;
+ }
+ }
}
-static afs_int32
-GetCell(char *fname, char *cellname)
+static CString
+GetCell(const CString & path)
{
+ char cellname[MAXCELLCHARS];
afs_int32 code;
struct ViceIoctl blob;
blob.in_size = 0;
- blob.out_size = MAXCELLCHARS;
+ blob.out_size = sizeof(cellname);
blob.out = cellname;
- code = pioctl(fname, VIOC_FILE_CELL_NAME, &blob, 1);
- return code ? errno : 0;
+ code = pioctl_T(path, VIOC_FILE_CELL_NAME, &blob, 1);
+ if (code) {
+ CString s;
+ s.Empty();
+
+ return s;
+ } else {
+ return Utf8ToCString(cellname);
+ }
}
register LONG code;
struct ViceIoctl blob;
int error;
- char orig_name[1024]; /* Original name, may be modified */
- char true_name[1024]; /* ``True'' dirname (e.g., symlink target) */
- char parent_dir[1024]; /* Parent directory of true name */
- register char *last_component; /* Last component of true name */
+
+ CString parent_dir; /* Parent directory of true name */
+ CStringUtf8 last_component; /* Last component of true name */
+
CStringArray mountPoints;
HOURGLASS hourglass;
error = 0;
for (int i = 0; i < files.GetSize(); i++) {
- strcpy(orig_name, files[i]);
- strcpy(true_name, orig_name);
+ int last_slash = files[i].ReverseFind(_T('\\'));
- /*
- * Find rightmost slash, if any.
- */
- last_component = (char *)strrchr(true_name, '\\');
- if (last_component) {
- /*
- * Found it. Designate everything before it as the parent directory,
- * everything after it as the final component.
- */
- strncpy(parent_dir, true_name, last_component - true_name + 1);
- parent_dir[last_component - true_name + 1] = 0;
- last_component++; /* Skip the slash */
-
- if (!IsPathInAfs(parent_dir)) {
- const char * nbname = NetbiosName();
- int len = strlen(nbname);
-
- if (parent_dir[0] == '\\' && parent_dir[1] == '\\' &&
- parent_dir[len+2] == '\\' &&
- parent_dir[len+3] == '\0' &&
- !strnicmp(nbname,&parent_dir[2],len))
- {
- sprintf(parent_dir,"\\\\%s\\all\\", nbname);
- }
+ if (last_slash != -1) {
+ last_component.SetString( files[i].Mid(last_slash + 1) );
+ parent_dir.SetString( files[i].Left(last_slash + 1) );
+ FixNetbiosPath(parent_dir);
+ } else {
+ // The path is of the form "C:foo" or just "foo". If
+ // there is a drive, then use the current directory of
+ // that drive. Otherwise we just use '.'.
+
+ if (files[i].GetLength() >= 2 && files[i][1] == _T(':')) {
+ parent_dir.Format(_T("%c:."), files[i][0]);
+ last_component.SetString( files[i].Mid(2) );
+ } else {
+ parent_dir.SetString( _T("."));
+ last_component.SetString( files[i] );
}
}
- else {
- /*
- * No slash appears in the given file name. Set parent_dir to the current
- * directory, and the last component as the given name.
- */
- fs_ExtractDriveLetter(true_name, parent_dir);
- strcat(parent_dir, ".");
- last_component = true_name;
- fs_StripDriveLetter(true_name, true_name, sizeof(true_name));
- }
- blob.in = last_component;
- blob.in_size = strlen(last_component) + 1;
+ blob.in_size = last_component.GetLength() + 1;
+ blob.in = last_component.GetBuffer();
blob.out_size = MAXSIZE;
blob.out = space;
memset(space, 0, MAXSIZE);
- code = pioctl(parent_dir, VIOC_AFS_STAT_MT_PT, &blob, 1);
+ code = pioctl_T(parent_dir, VIOC_AFS_STAT_MT_PT, &blob, 1);
+
+ last_component.ReleaseBuffer();
+
if (code == 0) {
int nPos = strlen(space) - 1;
if (space[nPos] == '.')
space[nPos] = 0;
- mountPoints.Add(ParseMountPoint(StripPath(files[i]), space));
+ mountPoints.Add(ParseMountPoint(StripPath(files[i]), Utf8ToCString(space)));
} else {
error = 1;
if (errno == EINVAL)
return !error;
}
-BOOL MakeMount(const CString& strDir, const CString& strVolName, const CString& strCellName, BOOL bRW)
+BOOL
+MakeMount(const CString& strDir,
+ const CString& strVolName,
+ const CString& strInCellName,
+ BOOL bRW)
{
- register LONG code;
- register char *cellName;
- char localCellName[128];
- struct afsconf_cell info;
-#if 0
- struct vldbentry vldbEntry;
-#endif
+ LONG code;
struct ViceIoctl blob;
- char * parent;
- char path[1024] = "";
-
HOURGLASS hourglass;
ASSERT(strVolName.GetLength() < 64);
- if (strCellName.GetLength() > 0) /* cell name specified */
- cellName = PCCHAR(strCellName);
- else
- cellName = (char *) 0;
-
- parent = Parent(PCCHAR(strDir));
- if (!IsPathInAfs(parent)) {
- const char * nbname = NetbiosName();
- int len = strlen(nbname);
-
- if (parent[0] == '\\' && parent[1] == '\\' &&
- parent[len+2] == '\\' &&
- parent[len+3] == '\0' &&
- !strnicmp(nbname,&parent[2],len))
- {
- sprintf(path,"%sall\\%s", parent, &(PCCHAR(strDir)[strlen(parent)]));
- parent = Parent(path);
- if (!IsPathInAfs(parent)) {
- ShowMessageBox(IDS_MAKE_MP_NOT_AFS_ERROR, MB_ICONERROR, IDS_MAKE_MP_NOT_AFS_ERROR);
- return FALSE;
- }
- } else {
+ CString strParent = Parent(strDir);
+
+ FixNetbiosPath(strParent);
+ if (!IsPathInAfs(strParent)) {
ShowMessageBox(IDS_MAKE_MP_NOT_AFS_ERROR, MB_ICONERROR, IDS_MAKE_MP_NOT_AFS_ERROR);
return FALSE;
}
- }
- if ( strlen(path) == 0 )
- strcpy(path, PCCHAR(strDir));
+ CString strPath = strParent + LastComponent(strDir);
- if ( IsFreelanceRoot(parent) ) {
- if ( !IsAdmin() ) {
- ShowMessageBox(IDS_NOT_AFS_CLIENT_ADMIN_ERROR, MB_ICONERROR, IDS_NOT_AFS_CLIENT_ADMIN_ERROR);
+ if ( IsFreelanceRoot(strParent) && !IsAdmin() ) {
+ ShowMessageBox(IDS_NOT_AFS_CLIENT_ADMIN_ERROR, MB_ICONERROR,
+ IDS_NOT_AFS_CLIENT_ADMIN_ERROR);
return FALSE;
}
- if (!cellName) {
- blob.in_size = 0;
- blob.out_size = sizeof(localCellName);
- blob.out = localCellName;
- code = pioctl(parent, VIOC_GET_WS_CELL, &blob, 1);
- if (!code)
- cellName = localCellName;
- }
- } else {
- if (!cellName)
- GetCell(parent,space);
- }
+ CString strMount;
- code = GetCellName(cellName?cellName:space, &info);
- if (code) {
- return FALSE;
- }
+ strMount.Format(_T("%c%s%s%s."),
+ ((bRW)?_T('%'):_T('#')),
+ strInCellName,
+ ((strInCellName.IsEmpty())?_T(""):_T(":")),
+ strVolName);
-#if 0
- code = VLDBInit(1, &info);
- if (code == 0) {
- /* make the check. Don't complain if there are problems with init */
- code = ubik_VL_GetEntryByNameO(uclient, 0, PCCHAR(strVolName), &vldbEntry);
- if (code == VL_NOENT) {
- ShowMessageBox(IDS_WARNING, MB_ICONWARNING, IDS_VOLUME_NOT_IN_CELL_WARNING,
- PCCHAR(strVolName), cellName ? cellName : space);
- }
- }
- if (rxInitDone)
- rx_Finalize();
-#endif
-
- if (bRW) /* if -rw specified */
- strcpy(space, "%");
- else
- strcpy(space, "#");
-
- /* If cellular mount point, prepend cell prefix */
- if (cellName) {
- strcat(space, info.name);
- strcat(space, ":");
- }
+ CStringUtf8 ustrMount(strMount);
- strcat(space, strVolName); /* append volume name */
- strcat(space, "."); /* stupid convention; these end with a period */
-
- /* create symlink with a special pioctl for Windows NT, since it doesn't
- * have a symlink system call.
- */
blob.out_size = 0;
- blob.in_size = 1 + strlen(space);
- blob.in = space;
+ blob.in_size = ustrMount.GetLength() + 1;
+ blob.in = ustrMount.GetBuffer();
blob.out = NULL;
- code = pioctl(path, VIOC_AFS_CREATE_MT_PT, &blob, 0);
+
+ code = pioctl_T(strPath, VIOC_AFS_CREATE_MT_PT, &blob, 0);
+
+ ustrMount.ReleaseBuffer();
if (code) {
ShowMessageBox(IDS_MOUNT_POINT_ERROR, MB_ICONERROR, IDS_MOUNT_POINT_ERROR, GetAfsError(errno, strDir));
}
-BOOL RemoveSymlink(const char * linkName)
+BOOL RemoveSymlink(const CString& strName)
{
BOOL error = FALSE;
INT code=0;
struct ViceIoctl blob;
- char tbuffer[1024];
char lsbuffer[1024];
- char tpbuffer[1024];
- char *tp;
HOURGLASS hourglass;
- tp = (char *) strrchr(linkName, '\\');
- if (!tp)
- tp = (char *) strrchr(linkName, '/');
- if (tp) {
- strncpy(tbuffer, linkName, code=tp-linkName+1); /* the dir name */
- tbuffer[code] = 0;
- tp++; /* skip the slash */
+ CString strParent = Parent(strName);
+ CStringUtf8 ustrLast(LastComponent(strName));
+ FixNetbiosPath(strParent);
- if (!IsPathInAfs(tbuffer)) {
- const char * nbname = NetbiosName();
- int len = strlen(nbname);
-
- if (tbuffer[0] == '\\' && tbuffer[1] == '\\' &&
- tbuffer[len+2] == '\\' &&
- tbuffer[len+3] == '\0' &&
- !strnicmp(nbname,&tbuffer[2],len))
- {
- sprintf(tbuffer,"\\\\%s\\all\\", nbname);
- }
- }
- }
- else {
- fs_ExtractDriveLetter(linkName, tbuffer);
- strcat(tbuffer, ".");
- fs_StripDriveLetter(tp, tpbuffer, 0);
- tp=tpbuffer;
- }
-
- if ( IsFreelanceRoot(tbuffer) && !IsAdmin() ) {
+ if ( IsFreelanceRoot(strParent) && !IsAdmin() ) {
ShowMessageBox(IDS_NOT_AFS_CLIENT_ADMIN_ERROR, MB_ICONERROR, IDS_NOT_AFS_CLIENT_ADMIN_ERROR);
return FALSE;
}
- blob.in = tp;
- blob.in_size = strlen(tp)+1;
+ blob.in_size = ustrLast.GetLength() + 1;
+ blob.in = ustrLast.GetBuffer();
blob.out = lsbuffer;
blob.out_size = sizeof(lsbuffer);
- code = pioctl(tbuffer, VIOC_LISTSYMLINK, &blob, 0);
+ code = pioctl_T(strParent, VIOC_LISTSYMLINK, &blob, 0);
+ ustrLast.ReleaseBuffer();
if (code)
return FALSE;
blob.out_size = 0;
- blob.in = tp;
- blob.in_size = strlen(tp)+1;
- return (pioctl(tbuffer, VIOC_DELSYMLINK, &blob, 0)==0);
+ blob.in_size = ustrLast.GetLength() + 1;
+ blob.in = ustrLast.GetBuffer();
+
+ code = pioctl_T(strParent, VIOC_DELSYMLINK, &blob, 0);
+
+ ustrLast.ReleaseBuffer();
+
+ return (code == 0);
}
-BOOL IsSymlink(const char * true_name)
+BOOL IsSymlink(const CString& strName)
{
- char parent_dir[MAXSIZE]; /*Parent directory of true name*/
- char strip_name[MAXSIZE];
struct ViceIoctl blob;
- char *last_component;
int code;
HOURGLASS hourglass;
- char buf[512];
- sprintf(buf, "IsSymlink(%s)", true_name);
- OutputDebugString(buf);
-
- last_component = (char *) strrchr(true_name, '\\');
- if (!last_component)
- last_component = (char *) strrchr(true_name, '/');
- if (last_component) {
- /*
- * Found it. Designate everything before it as the parent directory,
- * everything after it as the final component.
- */
- strncpy(parent_dir, true_name, last_component - true_name + 1);
- parent_dir[last_component - true_name + 1] = 0;
- last_component++; /*Skip the slash*/
-
- if (!IsPathInAfs(parent_dir)) {
- const char * nbname = NetbiosName();
- int len = strlen(nbname);
-
- if (parent_dir[0] == '\\' && parent_dir[1] == '\\' &&
- parent_dir[len+2] == '\\' &&
- parent_dir[len+3] == '\0' &&
- !strnicmp(nbname,&parent_dir[2],len))
{
- sprintf(parent_dir,"\\\\%s\\all\\", nbname);
- }
- }
- }
- else {
- /*
- * No slash appears in the given file name. Set parent_dir to the current
- * directory, and the last component as the given name.
- */
- fs_ExtractDriveLetter(true_name, parent_dir);
- strcat(parent_dir, ".");
- last_component = strip_name;
- fs_StripDriveLetter(true_name, strip_name, sizeof(strip_name));
+ CString str;
+ str.Format(_T("IsSymlink(%s)"), strName);
+ OutputDebugString(str);
}
- sprintf(buf, "last_component=%s", last_component);
- OutputDebugString(buf);
+ CStringUtf8 ustrLast(LastComponent(strName));
+ CString strParent = Parent(strName);
- blob.in = last_component;
- blob.in_size = strlen(last_component)+1;
+ FixNetbiosPath(strParent);
+
+ blob.in_size = ustrLast.GetLength() + 1;
+ blob.in = ustrLast.GetBuffer();
blob.out_size = MAXSIZE;
blob.out = space;
memset(space, 0, MAXSIZE);
- code = pioctl(parent_dir, VIOC_LISTSYMLINK, &blob, 1);
+
+ code = pioctl_T(strParent, VIOC_LISTSYMLINK, &blob, 1);
+
+ ustrLast.ReleaseBuffer();
+
return (code==0);
}
-BOOL IsMountPoint(const char * name)
+BOOL IsMountPoint(const CString& path)
{
register LONG code = 0;
struct ViceIoctl blob;
- char tbuffer[1024];
char lsbuffer[1024];
- register char *tp;
- char szCurItem[1024];
HOURGLASS hourglass;
- strcpy(szCurItem, name);
-
- char buf[512];
- sprintf(buf, "IsMountPoint(%s)", name);
- OutputDebugString(buf);
+ {
+ CString str;
+ str.Format(_T("IsMountPoint(%s)"), path);
+ OutputDebugString(str);
+ }
- tp = (char *)strrchr(szCurItem, '\\');
- if (tp) {
- strncpy(tbuffer, szCurItem, code = tp - szCurItem + 1); /* the dir name */
- tbuffer[code] = 0;
- tp++; /* skip the slash */
+ CString parent = Parent(path);
+ FixNetbiosPath(parent);
- if (!IsPathInAfs(tbuffer)) {
- const char * nbname = NetbiosName();
- int len = strlen(nbname);
+ CStringUtf8 mountpoint(LastComponent(path));
- if (tbuffer[0] == '\\' && tbuffer[1] == '\\' &&
- tbuffer[len+2] == '\\' &&
- tbuffer[len+3] == '\0' &&
- !strnicmp(nbname,&tbuffer[2],len))
{
- sprintf(tbuffer,"\\\\%s\\all\\", nbname);
- }
- }
- } else {
- fs_ExtractDriveLetter(szCurItem, tbuffer);
- strcat(tbuffer, ".");
- tp = szCurItem;
- fs_StripDriveLetter(tp, tp, 0);
+ CString str;
+#ifdef UNICODE
+ str.Format(_T("last_component=%S"), mountpoint);
+#else
+ str.Format(_T("last_component=%s"), mountpoint);
+#endif
+ OutputDebugString(str);
}
- sprintf(buf, "last_component=%s", tp);
- OutputDebugString(buf);
-
- blob.in = tp;
- blob.in_size = strlen(tp)+1;
+ blob.in_size = mountpoint.GetLength() + 1;
+ blob.in = mountpoint.GetBuffer();
blob.out = lsbuffer;
blob.out_size = sizeof(lsbuffer);
- code = pioctl(tbuffer, VIOC_AFS_STAT_MT_PT, &blob, 0);
+ code = pioctl_T(parent, VIOC_AFS_STAT_MT_PT, &blob, 0);
+
+ mountpoint.ReleaseBuffer();
return (code==0);
}
{
register LONG code = 0;
struct ViceIoctl blob;
- char tbuffer[1024];
- register char *tp;
- char szCurItem[1024];
BOOL error = FALSE;
CStringArray results;
CString str;
continue; // don't bother trying
}
- strcpy(szCurItem, files[i]);
-
- tp = (char *)strrchr(szCurItem, '\\');
- if (tp) {
- strncpy(tbuffer, szCurItem, code = tp - szCurItem + 1); /* the dir name */
- tbuffer[code] = 0;
- tp++; /* skip the slash */
-
- if (!IsPathInAfs(tbuffer)) {
- const char * nbname = NetbiosName();
- int len = strlen(nbname);
-
- if (tbuffer[0] == '\\' && tbuffer[1] == '\\' &&
- tbuffer[len+2] == '\\' &&
- tbuffer[len+3] == '\0' &&
- !strnicmp(nbname,&tbuffer[2],len))
- {
- sprintf(tbuffer,"\\\\%s\\all\\", nbname);
- }
- }
- } else {
- fs_ExtractDriveLetter(szCurItem, tbuffer);
- strcat(tbuffer, ".");
- tp = szCurItem;
- fs_StripDriveLetter(tp, tp, 0);
- }
+ CString parent = Parent(files[i]);
+ CStringUtf8 mountpoint(LastComponent(files[i]));
+ FixNetbiosPath(parent);
- if ( IsFreelanceRoot(tbuffer) && !IsAdmin() ) {
+ if ( IsFreelanceRoot(parent) && !IsAdmin() ) {
results.Add(GetMessageString(IDS_NOT_AFS_CLIENT_ADMIN_ERROR, StripPath(files[i])));
error = TRUE;
continue; /* skip */
}
blob.out_size = 0;
- blob.in = tp;
- blob.in_size = strlen(tp)+1;
+ blob.in_size = mountpoint.GetLength() + 1;
+ blob.in = mountpoint.GetBuffer();
+
+ code = pioctl_T(parent, VIOC_AFS_DELETE_MT_PT, &blob, 0);
+
+ mountpoint.ReleaseBuffer();
- code = pioctl(tbuffer, VIOC_AFS_DELETE_MT_PT, &blob, 0);
if (code) {
error = TRUE;
results.Add(GetMessageString(IDS_ERROR, GetAfsError(errno, StripPath(files[i]))));
blob.in_size = 0;
blob.out = space;
- code = pioctl(PCCHAR(strFile), VIOCGETVOLSTAT, &blob, 1);
+ code = pioctl_T(strFile, VIOCGETVOLSTAT, &blob, 1);
if (code) {
volInfo.m_strErrorMsg = GetAfsError(errno, strFile);
return FALSE;
status = (VolumeStatus *)space;
name = (char *)status + sizeof(*status);
- volInfo.m_strName = name;
+ volInfo.m_strName = Utf8ToCString(name);
volInfo.m_nID = status->Vid;
volInfo.m_nQuota = status->MaxQuota;
volInfo.m_nNewQuota = status->MaxQuota;
}
#endif
- code = pioctl(PCCHAR(volInfo.m_strFilePath), VIOCSETVOLSTAT, &blob, 1);
+ code = pioctl_T(volInfo.m_strFilePath, VIOCSETVOLSTAT, &blob, 1);
if (code) {
ShowMessageBox(IDS_SET_QUOTA_ERROR, MB_ICONERROR, IDS_SET_QUOTA_ERROR, GetAfsError(errno, volInfo.m_strName));
return FALSE;
return TRUE;
}
-int GetCellName(char *cellNamep, struct afsconf_cell *infop)
+void GetCellName(const CString& cellNamep, struct afsconf_cell *infop)
{
- strcpy(infop->name, cellNamep);
- return 0;
+ CStringUtf8 uCellName(cellNamep);
+
+ StringCbCopyA(infop->name, sizeof(infop->name), uCellName);
}
BOOL CheckServers(const CString& strCellName, WHICH_CELLS nCellsToCheck, BOOL bFast)
if (nCellsToCheck == SPECIFIC_CELL) {
temp = 2;
- GetCellName(PCCHAR(strCellName), &info);
+ GetCellName(strCellName, &info);
strcpy(checkserv.tbuffer,info.name);
checkserv.tsize = strlen(info.name) + 1;
} else {
checkserv.tflags = temp;
checkserv.tinterval = -1; /* don't change current interval */
- code = pioctl(0, VIOCCKSERV, &blob, 1);
+ code = pioctl_utf8(0, VIOCCKSERV, &blob, 1);
if (code) {
ShowMessageBox(IDS_CHECK_SERVERS_ERROR, MB_ICONERROR, IDS_CHECK_SERVERS_ERROR, GetAfsError(errno, CString()));
return FALSE;
expireString += 4; /* Skip day of week */
expireString[12] = '\0'; /* Omit secs & year */
// printf("[Expires %s]\n", expireString);
- strExpir.Format("%s", expireString);
+#ifdef UNICODE
+ strExpir.Format(_T("%S"), expireString);
+#else
+ strExpir.Format(_T("%s"), expireString);
+#endif
}
strTokenInfo = strUserName + "\t" + strCellName + "\t" + strExpir + "\t" + strCellName;
return TRUE;
}
-UINT MakeSymbolicLink(const char *strName, const char *strTarget)
+UINT MakeSymbolicLink(const CString& strName, const CString& strTarget)
{
struct ViceIoctl blob;
- char space[MAXSIZE];
- char * parent;
- char path[1024] = "";
UINT code;
-
HOURGLASS hourglass;
- static char message[2048];
- strcpy(path, strName);
- parent = Parent(path);
+ CString strParent = Parent(strName);
+ FixNetbiosPath(strParent);
- sprintf(message,"MakeSymbolicLink: name = %s target = %s parent = %s\n",strName,strTarget, parent);
- OutputDebugString(message);
+ {
+ CString str;
+ str.Format(_T("MakeSymbolicLink: name = %s target = %s parent = %s\n"),
+ strName, strTarget, strParent);
+ OutputDebugString(str);
+ }
- if ( IsFreelanceRoot(parent) && !IsAdmin() ) {
+ if ( IsFreelanceRoot(strParent) && !IsAdmin() ) {
ShowMessageBox(IDS_NOT_AFS_CLIENT_ADMIN_ERROR, MB_ICONERROR, IDS_NOT_AFS_CLIENT_ADMIN_ERROR);
return FALSE;
}
- LPTSTR lpsz = new TCHAR[strlen(strTarget)+1];
- _tcscpy(lpsz, strName);
- strcpy(space, strTarget);
+ CStringUtf8 ustrTarget(strTarget);
+
+ blob.in_size = ustrTarget.GetLength() + 1;
+ blob.in = ustrTarget.GetBuffer();
blob.out_size = 0;
- blob.in_size = 1 + strlen(space);
- blob.in = space;
blob.out = NULL;
- code=pioctl(lpsz, VIOC_SYMLINK, &blob, 0);
- delete lpsz;
+
+ code = pioctl_T(strName, VIOC_SYMLINK, &blob, 0);
+
+ ustrTarget.ReleaseBuffer();
+
if (code != 0)
return code;
- return FALSE;
+ return 0;
}
void ListSymbolicLinkPath(const char *strName,char *strPath,UINT nlenPath)
register LONG code;
struct ViceIoctl blob;
int error;
- char orig_name[1024]; /* Original name, may be modified */
- char true_name[1024]; /* ``True'' dirname (e.g., symlink target) */
- char parent_dir[1024]; /* Parent directory of true name */
- register char *last_component; /* Last component of true name */
CStringArray symlinks;
HOURGLASS hourglass;
error = 0;
for (int i = 0; i < files.GetSize(); i++) {
- strcpy(orig_name, files[i]);
- strcpy(true_name, orig_name);
- /*
- * Find rightmost slash, if any.
- */
- last_component = (char *)strrchr(true_name, '\\');
- if (last_component) {
- /*
- * Found it. Designate everything before it as the parent directory,
- * everything after it as the final component.
- */
- strncpy(parent_dir, true_name, last_component - true_name + 1);
- parent_dir[last_component - true_name + 1] = 0;
- last_component++; /* Skip the slash */
-
- if (!IsPathInAfs(parent_dir)) {
- const char * nbname = NetbiosName();
- int len = strlen(nbname);
-
- if (parent_dir[0] == '\\' && parent_dir[1] == '\\' &&
- parent_dir[len+2] == '\\' &&
- parent_dir[len+3] == '\0' &&
- !strnicmp(nbname,&parent_dir[2],len))
- {
- sprintf(parent_dir,"\\\\%s\\all\\", nbname);
- }
- }
- }
- else {
- /*
- * No slash appears in the given file name. Set parent_dir to the current
- * directory, and the last component as the given name.
- */
- fs_ExtractDriveLetter(true_name, parent_dir);
- strcat(parent_dir, ".");
- last_component = true_name;
- fs_StripDriveLetter(true_name, true_name, sizeof(true_name));
- }
+ CString strParent = Parent(files[i]);
+ CStringUtf8 ustrLast(LastComponent(files[i]));
+
+ FixNetbiosPath(strParent);
- blob.in = last_component;
- blob.in_size = strlen(last_component) + 1;
+ blob.in_size = ustrLast.GetLength() + 1;
+ blob.in = ustrLast.GetBuffer();
blob.out_size = MAXSIZE;
blob.out = space;
memset(space, 0, MAXSIZE);
- code = pioctl(parent_dir, VIOC_LISTSYMLINK, &blob, 1);
+ code = pioctl_T(strParent, VIOC_LISTSYMLINK, &blob, 1);
+
+ ustrLast.ReleaseBuffer();
+
if (code == 0) {
- int nPos = strlen(space) - 1;
- if (space[nPos] == '.')
- space[nPos] = 0;
- symlinks.Add(ParseSymlink(StripPath(files[i]), space));
+ CString syml = Utf8ToCString(space);
+ int len = syml.GetLength();
+
+ if (len > 0) {
+ if (syml[len - 1] == _T('.'))
+ syml.Truncate(len - 1);
+ }
+
+ symlinks.Add(ParseSymlink(StripPath(files[i]), syml));
+
} else {
error = 1;
if (errno == EINVAL)
void WhichCell(CStringArray& files);
BOOL CheckVolumes();
void SetCacheSize(LONG nNewCacheSize);
-void RemoveMountCmd(const CStringArray& files);
void WhereIs(CStringArray& files);
-CString GetAfsError(int code, const char *filename = 0);
+CString GetAfsError(int code, const TCHAR *filename = 0);
void CleanACL(CStringArray& names);
BOOL GetRights(const CString& strDir, CStringArray& strNormal, CStringArray& strNegative);
BOOL SaveACL(const CString& strCellName, const CString& strDir, const CStringArray& normal, const CStringArray& negative);
BOOL ListMount(CStringArray& files);
BOOL MakeMount(const CString& strDir, const CString& strVolName, const CString& strCellName, BOOL bRW);
BOOL RemoveMount(CStringArray& files);
-BOOL RemoveSymlink(const char *);
+BOOL RemoveSymlink(const CString& symlink);
BOOL GetVolumeInfo(CString strFile, CVolInfo& volInfo);
BOOL SetVolInfo(CVolInfo& volInfo);
enum WHICH_CELLS { LOCAL_CELL = 0, SPECIFIC_CELL = 1, ALL_CELLS = 2 };
BOOL CheckServers(const CString& strCellName, WHICH_CELLS nCellsToCheck, BOOL bFast);
BOOL GetTokenInfo(CStringArray& tokenInfo);
-BOOL IsPathInAfs(const CHAR *strPath);
-int GetCellName(char *baseNamep, struct afsconf_cell *infop);
-long fs_StripDriveLetter(const char *inPathp, char *outPathp, long outSize);
-long fs_ExtractDriveLetter(const char *inPathp, char *outPathp);
-BOOL IsSymlink(const char * true_name);
-BOOL IsMountPoint(const char * name);
-UINT MakeSymbolicLink(const char *,const char *);
-void ListSymbolicLinkPath(const char *strName,char *strPath,UINT nlenPath);
+BOOL IsPathInAfs(const CString& strPath);
+BOOL IsSymlink(const CString& name);
+BOOL IsMountPoint(const CString& name);
+UINT MakeSymbolicLink(const CString&,const CString&);
+void ListSymbolicLinkPath(CString&,CString&,UINT nlenPath);
BOOL ListSymlink(CStringArray& files);
-const char * NetbiosName(void);
#endif //__GUI2FS_H__
}
-
-void SetHelpPath(const char *pszDefaultHelpFilePath)
+void SetHelpPath(LPCTSTR pszDefaultHelpFilePath)
{
- CString str = pszDefaultHelpFilePath;
+ CString str(pszDefaultHelpFilePath);
int nIndex = str.ReverseFind('\\');
ASSERT(nIndex >= 0);
#define EDIT_PATH_NAME_HELP_ID 46
#define SYMLINK_HELP_ID 47
-void SetHelpPath(const char *pszDefaultHelpFilePath);
+void SetHelpPath(LPCTSTR pszDefaultHelpFilePath);
void ShowHelp(HWND hWnd, DWORD nHelpID);
HCURSOR m_OldCursor;
public:
- HOURGLASS (LPCSTR idCursor = IDC_WAIT)
+ HOURGLASS (LPTSTR idCursor = IDC_WAIT)
{
m_OldCursor = GetCursor();
SetCursor (LoadCursor (NULL, idCursor));
static char THIS_FILE[] = __FILE__;
#endif
+#ifdef UNICODE
+CStringA CStringToCStringA(const CString& str)
+{
+ CStringA astr(str);
+ return astr;
+}
+#define PCCHAR(str) ((char *)(const char *)CStringToCStringA(str))
+#else
#define PCCHAR(str) ((char *)(const char *)str)
-
+#endif
/////////////////////////////////////////////////////////////////////////////
// CKlogDlg dialog
-int kl_Authenticate(const CString& strCellName, const CString& strName, const CString& strPassword, char **reason)
+int kl_Authenticate(const CString& strCellName, const CString& strName,
+ const CString& strPassword, char **reason)
{
afs_int32 pw_exp;
- return ka_UserAuthenticateGeneral(KA_USERAUTH_VERSION, PCCHAR(strName), "", PCCHAR(strCellName), PCCHAR(strPassword), 0, &pw_exp, 0, reason);
+ return ka_UserAuthenticateGeneral(KA_USERAUTH_VERSION,
+ PCCHAR(strName), "",
+ PCCHAR(strCellName),
+ PCCHAR(strPassword),
+ 0,
+ &pw_exp, 0, reason);
}
CKlogDlg::CKlogDlg(CWnd* pParent /*=NULL*/)
char defaultCell[256];
long code = cm_GetRootCellName(defaultCell);
if (code < 0)
- AfxMessageBox("Error determining root cell name.");
+ AfxMessageBox(_T("Error determining root cell name."));
else
m_strCellName = defaultCell;
}
HOURGLASS hg;
if (kl_Authenticate(m_strCellName, m_strName, m_strPassword, &reason)) {
- AfxMessageBox(reason);
+ CString strReason(reason);
+ AfxMessageBox(strReason);
return;
}
#include <afs/stds.h>
}
-#include <string.h>
+#include <tchar.h>
#include <stdarg.h>
#include "msgs.h"
UINT ShowMessageBox (UINT Id, UINT Button, UINT Help, ...) {
CString temp;
- char *pszstring,
+ TCHAR *pszstring,
*pszpaste,
*pszcut,
*pszdone,
*pszconvert;
- char chread;
+ TCHAR chread;
va_list params;
int x;
- pszconvert = new char[255];
+ pszconvert = new TCHAR[255];
va_start(params, Help);
LoadString (temp, Id);
pszstring = temp.GetBuffer(512);
- strcpy(pszstring,pszstring);
+ _tcscpy(pszstring,pszstring);
temp.ReleaseBuffer();
// Look and see - is there a need to insert chars (95% of the time, there won't)
- if (!strstr(pszstring, "%")) {
+ if (!_tcsstr(pszstring, _T("%"))) {
delete pszconvert;
return AfxMessageBox(pszstring, Button, Help);
}
- x = strcspn(pszstring, "%");
- pszdone = new char[512];
- pszcut = new char[512];
- pszpaste = new char[512];
- strcpy(pszcut, &pszstring[x+2]);
- strncpy(pszpaste, pszstring, x);
- pszpaste[x] = '\0';
+ x = _tcscspn(pszstring, _T("%"));
+ pszdone = new TCHAR[512];
+ pszcut = new TCHAR[512];
+ pszpaste = new TCHAR[512];
+ _tcscpy(pszcut, &pszstring[x+2]);
+ _tcsncpy(pszpaste, pszstring, x);
+ pszpaste[x] = _T('\0');
chread = pszstring[x+1];
for ( ; ; ) {
switch (chread) {
- case 'i' :
- case 'd' :
+ case _T('i') :
+ case _T('d') :
{
int anint = va_arg(params, int);
- _itoa( anint, pszconvert, 10);
+ _itot( anint, pszconvert, 10);
break;
}
- case 'u' :
+ case _T('u') :
{
UINT anuint = va_arg(params, UINT);
- _itoa( anuint, pszconvert, 10);
+ _itot( anuint, pszconvert, 10);
break;
}
- case 'x' :
- case 'X' :
+ case _T('x') :
+ case _T('X') :
{
int ahex = va_arg(params, int);
- _itoa( ahex, pszconvert, 16);
+ _itot( ahex, pszconvert, 16);
break;
}
- case 'g' :
- case 'f' :
- case 'e' :
+ case _T('g') :
+ case _T('f') :
+ case _T('e') :
{
double adbl = va_arg(params, double);
- _gcvt( adbl, 10, pszconvert);
+ _stprintf(pszconvert, _T("%g"), adbl);
break;
}
- case 's' :
+ case _T('s') :
{
- char *pStr = va_arg(params, char*);
- ASSERT(strlen(pStr) <= 255);
- strcpy(pszconvert, pStr);
+ TCHAR *pStr = va_arg(params, TCHAR*);
+ ASSERT(_tcslen(pStr) <= 255);
+ _tcscpy(pszconvert, pStr);
break;
}
- case 'l' :
+ case _T('l') :
{
chread = pszdone[x+2];
switch(chread) {
- case 'x' :
+ case _T('x') :
{
long int alhex = va_arg(params, long int);
- _ltoa(alhex, pszconvert, 16);
- strcpy(pszcut, &pszcut[1]);
+ _ltot(alhex, pszconvert, 16);
+ _tcscpy(pszcut, &pszcut[1]);
break;
}
- case 'd' :
+ case _T('d') :
default :
{
long int along = va_arg(params, long int);
- _ltoa( along, pszconvert, 10);
+ _ltot( along, pszconvert, 10);
// For the L, there will be one character after it,
// so move ahead another letter
- strcpy(pszcut, &pszcut[1]);
+ _tcscpy(pszcut, &pszcut[1]);
break;
}
}
break;
}
- case 'c' :
+ case _T('c') :
{
int letter = va_arg(params, int);
- pszconvert[0] = (char)letter;
+ pszconvert[0] = (TCHAR)letter;
pszconvert[1] = '\0';
break;
}
- case 'a' :
+ case _T('a') :
{
CString zeta;
- char* lsc;
+ TCHAR* lsc;
UINT ls = va_arg(params, UINT);
LoadString (zeta, ls);
lsc = zeta.GetBuffer(255);
- strcpy(pszconvert, lsc);
+ _tcscpy(pszconvert, lsc);
zeta.ReleaseBuffer();
break;
}
- case 'o' :
+ case _T('o') :
{
CString get = va_arg(params, CString);
- char* ex = get.GetBuffer(255);
- strcpy(pszconvert,ex);
+ TCHAR* ex = get.GetBuffer(255);
+ _tcscpy(pszconvert,ex);
get.ReleaseBuffer();
break;
}
default :
{
- strcpy(pszconvert, " Could not load message. Invalid %type in string table entry. ");
+ _tcscpy(pszconvert, _T(" Could not load message. Invalid %type in string table entry. "));
delete pszdone;
- pszdone = new char[strlen(pszpaste)+strlen(pszcut)+strlen(pszconvert)+5];
- strcpy(pszdone, pszpaste);
- strcat(pszdone, pszconvert);
- strcat(pszdone, pszcut);
+ pszdone = new TCHAR[_tcslen(pszpaste)+_tcslen(pszcut)+_tcslen(pszconvert)+5];
+ _tcscpy(pszdone, pszpaste);
+ _tcscat(pszdone, pszconvert);
+ _tcscat(pszdone, pszcut);
AfxMessageBox(pszdone, Button, Help);
delete pszcut;
delete pszpaste;
} // case
delete pszdone;
- pszdone = new char[strlen(pszpaste)+strlen(pszcut)+strlen(pszconvert)+5];
- strcpy(pszdone, pszpaste);
- strcat(pszdone, pszconvert);
- strcat(pszdone, pszcut);
+ pszdone = new TCHAR[_tcslen(pszpaste)+_tcslen(pszcut)+_tcslen(pszconvert)+5];
+ _tcscpy(pszdone, pszpaste);
+ _tcscat(pszdone, pszconvert);
+ _tcscat(pszdone, pszcut);
// Now pszdone holds the entire message.
// Check to see if there are more insertions to be made or not
- if (!strstr(pszdone, "%")) {
+ if (!_tcsstr(pszdone, _T("%"))) {
UINT rt_type = AfxMessageBox(pszdone, Button, Help);
delete pszcut;
delete pszpaste;
} // if
// there are more insertions to make, prepare the strings to use.
- x = strcspn(pszdone, "%");
- strcpy(pszcut, &pszdone[x+2]);
- strncpy(pszpaste, pszdone, x);
- pszpaste[x] = '\0';
+ x = _tcscspn(pszdone, _T("%"));
+ _tcscpy(pszcut, &pszdone[x+2]);
+ _tcsncpy(pszpaste, pszdone, x);
+ pszpaste[x] = _T('\0');
chread = pszdone[x+1];
} // for
CString GetMessageString(UINT Id, ...)
{
CString temp;
- char *pszstring,
+ TCHAR *pszstring,
*pszpaste,
*pszcut,
*pszdone,
*pszconvert;
- char chread;
+ TCHAR chread;
va_list params;
int x;
CString strMsg;
- pszconvert = new char[255];
+ pszconvert = new TCHAR[255];
va_start(params, Id);
LoadString (temp, Id);
pszstring = temp.GetBuffer(512);
- strcpy(pszconvert,pszstring);
+ _tcscpy(pszconvert,pszstring);
temp.ReleaseBuffer();
// Look and see - is there a need to insert chars (95% of the time, there won't)
- if (!strstr(pszstring, "%")) {
+ if (!_tcsstr(pszstring, _T("%"))) {
strMsg = pszconvert;
delete pszconvert;
return strMsg;
}
- x = strcspn(pszstring, "%");
- pszdone = new char[512];
- pszcut = new char[512];
- pszpaste = new char[512];
- strcpy(pszcut, &pszstring[x+2]);
- strncpy(pszpaste, pszstring, x);
- pszpaste[x] = '\0';
+ x = _tcscspn(pszstring, _T("%"));
+ pszdone = new TCHAR[512];
+ pszcut = new TCHAR[512];
+ pszpaste = new TCHAR[512];
+ _tcscpy(pszcut, &pszstring[x+2]);
+ _tcsncpy(pszpaste, pszstring, x);
+ pszpaste[x] = _T('\0');
chread = pszstring[x+1];
for ( ; ; ) {
switch (chread) {
- case 'i' :
- case 'd' :
+ case _T('i') :
+ case _T('d') :
{
int anint = va_arg(params, int);
- _itoa( anint, pszconvert, 10);
+ _itot( anint, pszconvert, 10);
break;
}
- case 'u' :
+ case _T('u') :
{
UINT anuint = va_arg(params, UINT);
- _itoa( anuint, pszconvert, 10);
+ _itot( anuint, pszconvert, 10);
break;
}
- case 'x' :
- case 'X' :
+ case _T('x') :
+ case _T('X') :
{
int ahex = va_arg(params, int);
- _itoa( ahex, pszconvert, 16);
+ _itot( ahex, pszconvert, 16);
break;
}
- case 'g' :
- case 'f' :
- case 'e' :
+ case _T('g') :
+ case _T('f') :
+ case _T('e') :
{
double adbl = va_arg(params, double);
- _gcvt( adbl, 10, pszconvert);
+ _stprintf(pszconvert, _T("%g"), adbl);
break;
}
- case 's' :
+ case _T('s') :
{
- char *pStr = va_arg(params, char*);
- ASSERT(strlen(pStr) <= 255);
- strcpy(pszconvert, pStr);
+ TCHAR *pStr = va_arg(params, TCHAR*);
+ ASSERT(_tcslen(pStr) <= 255);
+ _tcscpy(pszconvert, pStr);
break;
}
- case 'l' :
+ case _T('l') :
{
chread = pszdone[x+2];
switch(chread) {
- case 'x' :
+ case _T('x') :
{
long int alhex = va_arg(params, long int);
- _ltoa(alhex, pszconvert, 16);
- strcpy(pszcut, &pszcut[1]);
+ _ltot(alhex, pszconvert, 16);
+ _tcscpy(pszcut, &pszcut[1]);
break;
}
- case 'd' :
+ case _T('d') :
default :
{
long int along = va_arg(params, long int);
- _ltoa( along, pszconvert, 10);
+ _ltot( along, pszconvert, 10);
// For the L, there will be one character after it,
// so move ahead another letter
- strcpy(pszcut, &pszcut[1]);
+ _tcscpy(pszcut, &pszcut[1]);
break;
}
}
break;
}
- case 'c' :
+ case _T('c') :
{
int letter = va_arg(params, int);
- pszconvert[0] = (char)letter;
- pszconvert[1] = '\0';
+ pszconvert[0] = (TCHAR)letter;
+ pszconvert[1] = _T('\0');
break;
}
- case 'a' :
+ case _T('a') :
{
CString zeta;
- char* lsc;
+ TCHAR* lsc;
UINT ls = va_arg(params, UINT);
LoadString (zeta, ls);
lsc = zeta.GetBuffer(255);
- strcpy(pszconvert, lsc);
+ _tcscpy(pszconvert, lsc);
zeta.ReleaseBuffer();
break;
}
- case 'o' :
+ case _T('o') :
{
CString get = va_arg(params, CString);
- char* ex = get.GetBuffer(255);
- strcpy(pszconvert,ex);
+ TCHAR* ex = get.GetBuffer(255);
+ _tcscpy(pszconvert,ex);
get.ReleaseBuffer();
break;
}
default:
{
- strcpy(pszconvert, " Could not load message. Invalid %type in string table entry. ");
+ _tcscpy(pszconvert, _T(" Could not load message. Invalid %type in string table entry. "));
delete pszdone;
- pszdone = new char[strlen(pszpaste)+strlen(pszcut)+strlen(pszconvert)+5];
- strcpy(pszdone, pszpaste);
- strcat(pszdone, pszconvert);
- strcat(pszdone, pszcut);
+ pszdone = new TCHAR[_tcslen(pszpaste)+_tcslen(pszcut)+_tcslen(pszconvert)+5];
+ _tcscpy(pszdone, pszpaste);
+ _tcscat(pszdone, pszconvert);
+ _tcscat(pszdone, pszcut);
strMsg = pszdone;
delete pszcut;
delete pszpaste;
} // case
delete pszdone;
- pszdone = new char[strlen(pszpaste)+strlen(pszcut)+strlen(pszconvert)+5];
- strcpy(pszdone, pszpaste);
- strcat(pszdone, pszconvert);
- strcat(pszdone, pszcut);
+ pszdone = new TCHAR[_tcslen(pszpaste)+_tcslen(pszcut)+_tcslen(pszconvert)+5];
+ _tcscpy(pszdone, pszpaste);
+ _tcscat(pszdone, pszconvert);
+ _tcscat(pszdone, pszcut);
// Now pszdone holds the entire message.
// Check to see if there are more insertions to be made or not
- if (!strstr(pszdone, "%")) {
+ if (!_tcsstr(pszdone, _T("%"))) {
strMsg = pszdone;
delete pszcut;
delete pszpaste;
} // if
// there are more insertions to make, prepare the strings to use.
- x = strcspn(pszdone, "%");
- strcpy(pszcut, &pszdone[x+2]);
- strncpy(pszpaste, pszdone, x);
- pszpaste[x] = '\0';
+ x = _tcscspn(pszdone, _T("%"));
+ _tcscpy(pszcut, &pszdone[x+2]);
+ _tcsncpy(pszpaste, pszdone, x);
+ pszpaste[x] = _T('\0');
chread = pszdone[x+1];
} // for
void LoadString (CString &Str, UINT id)
{
- TCHAR szString[ 256 ];
+ extern EXPORTED void GetString (LPSTR pszTarget, int idsSource, int cchMax = cchRESOURCE);
+
+ char szString[ 256 ];
GetString (szString, id);
+#ifdef UNICODE
+ CString wstr(szString);
+ Str = wstr;
+#else
Str = szString;
+#endif
}
ASSERT(m_nSize != 0);
CString strSize;
- strSize.Format("%ld", m_nSize);
+ strSize.Format(_T("%ld"), m_nSize);
CString strFree;
- strFree.Format("%ld", m_nFree);
+ strFree.Format(_T("%ld"), m_nFree);
CString strPerUsed;
- strPerUsed.Format("%d", ((m_nSize - m_nFree) * 100) / m_nSize);
+ strPerUsed.Format(_T("%d"), ((m_nSize - m_nFree) * 100) / m_nSize);
m_Size.SetWindowText(strSize);
m_Free.SetWindowText(strFree);
percentUsed = ( double(m_nSize - m_nFree) * 100.0l ) / double(m_nSize);
- strPerUsed.Format("%2.2lf", percentUsed );
+ strPerUsed.Format(_T("%2.2lf"), percentUsed );
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
int i;
for (i = 0; i < m_Normal.GetSize(); i += 2)
- m_NormalRights.AddString(m_Normal[i + 1] + "\t" + m_Normal[i]);
+ m_NormalRights.AddString(m_Normal[i + 1] + _T("\t") + m_Normal[i]);
for (i = 0; i < m_Negative.GetSize(); i += 2)
- m_NegativeRights.AddString(m_Negative[i + 1] + "\t" + m_Negative[i]);
+ m_NegativeRights.AddString(m_Negative[i + 1] + _T("\t") + m_Negative[i]);
CenterWindow();
if (bNormal) {
m_Normal.Add(name);
m_Normal.Add(rights);
- m_nCurSel = m_NormalRights.AddString(rights + "\t" + name);
+ m_nCurSel = m_NormalRights.AddString(rights + _T("\t") + name);
m_NormalRights.SetSel(m_nCurSel);
m_bShowingNormal = TRUE;
} else {
m_Negative.Add(name);
m_Negative.Add(rights);
- m_nCurSel = m_NegativeRights.AddString(rights + "\t" + name);
+ m_nCurSel = m_NegativeRights.AddString(rights + _T("\t") + name);
m_NegativeRights.SetSel(m_nCurSel);
m_bShowingNormal = FALSE;
}
void CSetAfsAcl::ShowRights(const CString& strRights)
{
- m_ReadPerm.SetCheck((strRights.Find("r") == -1) ? UNCHECKED : CHECKED);
- m_WritePerm.SetCheck((strRights.Find("w") == -1) ? UNCHECKED : CHECKED);
- m_LookupPerm.SetCheck((strRights.Find("l") == -1) ? UNCHECKED : CHECKED);
- m_DeletePerm.SetCheck((strRights.Find("d") == -1) ? UNCHECKED : CHECKED);
- m_InsertPerm.SetCheck((strRights.Find("i") == -1) ? UNCHECKED : CHECKED);
- m_LockPerm.SetCheck((strRights.Find("k") == -1) ? UNCHECKED : CHECKED);
- m_AdminPerm.SetCheck((strRights.Find("a") == -1) ? UNCHECKED : CHECKED);
+ m_ReadPerm.SetCheck((strRights.Find(_T("r")) == -1) ? UNCHECKED : CHECKED);
+ m_WritePerm.SetCheck((strRights.Find(_T("w")) == -1) ? UNCHECKED : CHECKED);
+ m_LookupPerm.SetCheck((strRights.Find(_T("l")) == -1) ? UNCHECKED : CHECKED);
+ m_DeletePerm.SetCheck((strRights.Find(_T("d")) == -1) ? UNCHECKED : CHECKED);
+ m_InsertPerm.SetCheck((strRights.Find(_T("i")) == -1) ? UNCHECKED : CHECKED);
+ m_LockPerm.SetCheck((strRights.Find(_T("k")) == -1) ? UNCHECKED : CHECKED);
+ m_AdminPerm.SetCheck((strRights.Find(_T("a")) == -1) ? UNCHECKED : CHECKED);
}
void CSetAfsAcl::OnSelChangeNormalRights()
int nNum = m_NormalRights.GetSelCount();
if (nNum != 1) {
- ShowRights("");
+ ShowRights(_T(""));
EnablePermChanges(FALSE);
return;
}
int nNum = m_NegativeRights.GetSelCount();
if (nNum != 1) {
- ShowRights("");
+ ShowRights(_T(""));
EnablePermChanges(FALSE);
return;
}
CString str;
if (m_ReadPerm.GetCheck() == CHECKED)
- str += "r";
+ str += _T("r");
if (m_LookupPerm.GetCheck() == CHECKED)
- str += "l";
+ str += _T("l");
if (m_InsertPerm.GetCheck() == CHECKED)
- str += "i";
+ str += _T("i");
if (m_DeletePerm.GetCheck() == CHECKED)
- str += "d";
+ str += _T("d");
if (m_WritePerm.GetCheck() == CHECKED)
- str += "w";
+ str += _T("w");
if (m_LockPerm.GetCheck() == CHECKED)
- str += "k";
+ str += _T("k");
if (m_AdminPerm.GetCheck() == CHECKED)
- str += "a";
+ str += _T("a");
return str;
}
CString str = MakeRightsString();
(*pRights)[(2 * m_nCurSel) + 1] = str;
- str += "\t" + (*pRights)[(2 * m_nCurSel)];
+ str += _T("\t") + (*pRights)[(2 * m_nCurSel)];
pRightsList->DeleteString(m_nCurSel);
pRightsList->InsertString(m_nCurSel, str);
{
m_NegativeRights.SetSel(i, FALSE);
}
- ShowRights(""); // Show no rights
+ ShowRights(_T("")); // Show no rights
EnablePermChanges(FALSE); // Allow no rights changes
m_Remove.EnableWindow(FALSE); // Disable remove button
}
{
struct _stat statbuf;
- if (_stat(strName, &statbuf) < 0)
+ if (_tstat(strName, &statbuf) < 0)
return FALSE;
return statbuf.st_mode & _S_IFDIR;
m_bIsOverlayEnabled=FALSE;
if (FAILED(hr))
m_pAlloc = NULL;
- RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,0, (IsWow64()?KEY_WOW64_64KEY:0)|KEY_QUERY_VALUE, &NPKey);
+ RegOpenKeyExA(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,0, (IsWow64()?KEY_WOW64_64KEY:0)|KEY_QUERY_VALUE, &NPKey);
LSPsize=sizeof(ShellOption);
- code=RegQueryValueEx(NPKey, "ShellOption", NULL,
+ code=RegQueryValueEx(NPKey, _T("ShellOption"), NULL,
&LSPtype, (LPBYTE)&ShellOption, &LSPsize);
RegCloseKey (NPKey);
m_bIsOverlayEnabled=((code==0) && (LSPtype==REG_DWORD) && ((ShellOption & OVERLAYENABLED)!=0));
DeleteMenu (hMenu, iItem, MF_BYPOSITION);
continue;
}
- if ((!lstrcmp(szItemText,"&Delete"))&&(pThis->m_bIsSymlink)) { /*this is a symlink - don't present a delete menu!*/
+ if ((!lstrcmp(szItemText,_T("&Delete")))&&(pThis->m_bIsSymlink)) { /*this is a symlink - don't present a delete menu!*/
DeleteMenu (hMenu, iItem, MF_BYPOSITION);
continue;
}
- if ((!lstrcmp(szItemText,"Cu&t"))&&(pThis->m_bIsSymlink)) { /*same for cut*/
+ if ((!lstrcmp(szItemText,_T("Cu&t")))&&(pThis->m_bIsSymlink)) { /*same for cut*/
DeleteMenu (hMenu, iItem, MF_BYPOSITION);
continue;
}
}
case IDM_SYMBOLICLINK_ADD: {
- CString msg=files.GetAt(0);
+ CStringA msg(files.GetAt(0));
int i;
if ((i=msg.ReverseFind('\\'))>0)
msg=msg.Left(i+1);
CString strMsg;
LoadString (strMsg, nCmdStrID);
- strncpy(pszName, strMsg, cchMax);
+ _tcsncpy((LPTSTR) pszName, strMsg, cchMax);
return NOERROR;
}
if(IsBadWritePtr(pdwFlags, sizeof(DWORD)))
return E_INVALIDARG;
- HMODULE hModule=GetModuleHandle("shell32.dll");
+ HMODULE hModule=GetModuleHandle(_T("shell32.dll"));
TCHAR szModule[MAX_PATH];
DWORD z=GetModuleFileName(hModule,szModule,sizeof(szModule));
+#ifndef UNICODE
MultiByteToWideChar( CP_ACP,0,szModule,-1,pwszIconFile,cchMax);
+#else
+ _tcsncpy(pwszIconFile, szModule, cchMax);
+#endif
*pIndex = 30;
*pdwFlags = ISIOI_ICONFILE | ISIOI_ICONINDEX;
return S_OK;
STDMETHODIMP CShellExt::XIconExt::IsMemberOf(LPCWSTR pwszPath,DWORD dwAttrib)
{
TCHAR szPath[MAX_PATH];
+#ifdef UNICODE
+ _tcscpy(szPath, pwszPath);
+#else
WideCharToMultiByte( CP_ACP,0,pwszPath,-1,szPath,MAX_PATH,NULL,NULL);
+#endif
if (IsSymlink(szPath))
return S_OK;
return S_FALSE;
extern ULONG nTPRefCount; // IQueryInfo ref count
extern ULONG nXPRefCount; // IPersistFile ref count
-#define STR_EXT_TITLE TEXT("AfsClientContextMenu")
+#define STR_EXT_TITLE "AfsClientContextMenu"
#define STR_REG_PATH TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ShellIconOverlayIdentifiers")
/////////////////////////////////////////////////////////////////////////////
DWORD len;
- char pathName[1024];
+ TCHAR pathName[1024];
HKEY hkSubmounts;
- RegCreateKeyEx( HKEY_LOCAL_MACHINE,
+ RegCreateKeyExA( HKEY_LOCAL_MACHINE,
AFSREG_CLT_OPENAFS_SUBKEY "\\Submounts",
0,
"AFS",
DWORD dwType;
DWORD status;
len = sizeof(pathName);
- status = RegQueryValueEx( hkSubmounts, (LPCSTR)PCCHAR(strShareName), 0,
+ status = RegQueryValueEx( hkSubmounts, strShareName, 0,
&dwType, (LPBYTE)pathName, &len);
RegCloseKey( hkSubmounts );
DWORD dwIndex;
DWORD dwSubmounts;
- RegCreateKeyEx( HKEY_LOCAL_MACHINE,
+ RegCreateKeyExA( HKEY_LOCAL_MACHINE,
AFSREG_CLT_OPENAFS_SUBKEY "\\Submounts",
0,
"AFS",
for ( dwIndex = 0; dwIndex < dwSubmounts; dwIndex ++ ) {
- char submountName[256];
+ TCHAR submountName[256];
DWORD submountNameLen = sizeof(submountName);
RegEnumValue( hkSubmounts, dwIndex, submountName, &submountNameLen, NULL,
ASSERT(!strSubmt.IsEmpty());
- strShareName = strSubmt.SpanExcluding("=");
+ strShareName = strSubmt.SpanExcluding(_T("="));
if (ShowMessageBox(IDS_REALLY_DELETE_SUBMT, MB_YESNO | MB_ICONQUESTION, IDS_REALLY_DELETE_SUBMT, strShareName) != IDYES)
return;
HOURGLASS hourglass;
HKEY hkSubmounts;
- RegCreateKeyEx( HKEY_LOCAL_MACHINE,
+ RegCreateKeyExA( HKEY_LOCAL_MACHINE,
AFSREG_CLT_OPENAFS_SUBKEY "\\Submounts",
0,
"AFS",
&hkSubmounts,
NULL );
- DWORD status = RegSetValueEx( hkSubmounts, PCCHAR(pInfo->GetShareName()), 0, REG_SZ,
- (const BYTE *)PCCHAR(pInfo->GetPathName()), strlen(PCCHAR(pInfo->GetPathName())) + 1);
+ DWORD status = RegSetValueEx( hkSubmounts, pInfo->GetShareName(), 0, REG_SZ,
+ (const BYTE *)(const TCHAR *) pInfo->GetPathName(),
+ pInfo->GetPathName().GetLength() + 1);
RegCloseKey(hkSubmounts);
return (status == ERROR_SUCCESS);
HOURGLASS hourglass;
HKEY hkSubmounts;
- RegCreateKeyEx( HKEY_LOCAL_MACHINE,
+ RegCreateKeyExA( HKEY_LOCAL_MACHINE,
AFSREG_CLT_OPENAFS_SUBKEY "\\Submounts",
0,
"AFS",
&hkSubmounts,
NULL );
- DWORD status = RegDeleteValue( hkSubmounts, PCCHAR(pInfo->GetShareName()));
+ DWORD status = RegDeleteValue( hkSubmounts, pInfo->GetShareName());
RegCloseKey(hkSubmounts);
return (status == ERROR_SUCCESS);
ASSERT(!strSubmt.IsEmpty());
- strShareName = strSubmt.SpanExcluding("=");
+ strShareName = strSubmt.SpanExcluding(_T("="));
CSubmountInfo *pInfo = FindWork(strShareName);
if (pInfo != 0)
char defaultCell[256];
long code = cm_GetRootCellName(defaultCell);
if (code < 0)
- AfxMessageBox("Error determining root cell name.");
+ AfxMessageBox(_T("Error determining root cell name."));
else
m_strCellName = defaultCell;
}
{
struct ktc_principal server;
int code;
- static char xreason[100];
if (strCellName.IsEmpty())
code = ktc_ForgetAllTokens();
else {
- strcpy(server.cell, strCellName);
+ CStringA astrCellName(strCellName);
+
+ strcpy(server.cell, astrCellName);
server.instance[0] = '\0';
strcpy(server.name, "afs");
code = ktc_ForgetToken(&server);
}
if (code == KTC_NOCM)
- AfxMessageBox("AFS service may not have started");
+ AfxMessageBox(_T("AFS service may not have started"));
else if (code) {
- sprintf(xreason, "Unexpected error, code %d", code);
+ CString xreason;
+
+ xreason.Format(_T("Unexpected error, code %d"), code);
AfxMessageBox(xreason);
}
if (nQuota != 0) {
LONG nPercentUsed = (m_pVolInfo[i].m_nUsed * 100) / nQuota;
- strEntry.Format("%s\t%s\t%ld\t%ldK\t%ldK\t%ld%%", m_pVolInfo[i].m_strFileName, m_pVolInfo[i].m_strName,
- m_pVolInfo[i].m_nID, nQuota, m_pVolInfo[i].m_nUsed, nPercentUsed);
+ strEntry.Format(_T("%s\t%s\t%ld\t%ldK\t%ldK\t%ld%%"),
+ m_pVolInfo[i].m_strFileName,
+ m_pVolInfo[i].m_strName,
+ m_pVolInfo[i].m_nID, nQuota,
+ m_pVolInfo[i].m_nUsed, nPercentUsed);
} else {
- strEntry.Format("%s\t%s\t%ld\tUnlimited\t%ldK", m_pVolInfo[i].m_strFileName, m_pVolInfo[i].m_strName,
+ strEntry.Format(_T("%s\t%s\t%ld\tUnlimited\t%ldK"),
+ m_pVolInfo[i].m_strFileName,
+ m_pVolInfo[i].m_strName,
m_pVolInfo[i].m_nID, m_pVolInfo[i].m_nUsed);
}
}
#sanity checks
+!IF ("$(CPU)" != "x86")
+CPU=i386
+!ENDIF
+
!IF ("$(CPU)" != "i386")
!ERROR Platform SDK not configured for i386
!ENDIF
LIB = $(AFSDEV_LIB)
#define used in WinNT/2000 installation and program version display
-AFSPRODUCT_VER_MAJOR=0
+AFSPRODUCT_VER_MAJOR=2
AFSPRODUCT_VER_MINOR=0
AFSPRODUCT_VER_PATCH=0
AFSPRODUCT_VER_BUILD=0
-DAFS_64BIT_ENV \
-DAFS_64BIT_CLIENT \
-DAFS_LARGEFILE_ENV \
+ -DAFS_OLD_COM_ERR \
$(AFSDEV_AUXCDEFINES)
# Compiler switches (except include paths and preprocessor defines)
VOTE_GetSyncSite @113
ubik_RefreshConn @114
rx_SetSecurityConfiguration @115
+ pioctl_utf8 @116
REM Location of netmpr.h/netspi.h (from Windows 95/98 DDK - 8.3 short name)
SET W9XDDKDIR=c:\progra~1\micros~6
+REM Location of Microsoft IDN Normalization SDK
+set MSIDNNLS=C:\progra~1\MI5913~1
+
REM ########################################################################
REM NTMakefile optional definitions:
REM
set AFSDEV_BUILDTYPE=%AFSBLD_TYPE%
-set AFSDEV_INCLUDE=%MSSDKDIR%\include;%MSVCDIR%\include
+set AFSDEV_INCLUDE=%MSSDKDIR%\include;%MSVCDIR%\include;%MSIDNNLS%\include
IF "%AFSVER_CL%" == "1400" set AFSDEV_INCLUDE=%AFSDEV_INCLUDE%;%MSVCDIR%\atlmfc\include
IF "%AFSVER_CL%" == "1310" set AFSDEV_INCLUDE=%AFSDEV_INCLUDE%;%MSVCDIR%\atlmfc\include
IF "%AFSVER_CL%" == "1300" set AFSDEV_INCLUDE=%AFSDEV_INCLUDE%;%MSVCDIR%\atlmfc\include
static char AFSConfigKeyName[] = AFSREG_CLT_SVC_PARAM_SUBKEY;
+static const char utf8_prefix[] = UTF8_PREFIX;
+static const int utf8_prefix_size = sizeof(utf8_prefix) - sizeof(char);
+
#define FS_IOCTLREQUEST_MAXSIZE 8192
/* big structure for representing and storing an IOCTL request */
typedef struct fs_ioctlRequest {
/* includes marshalling NULL pointer as a null (0 length) string */
static long
-MarshallString(fs_ioctlRequest_t * reqp, char *stringp)
+MarshallString(fs_ioctlRequest_t * reqp, char *stringp, int is_utf8)
{
int count;
else
count = 1;
+ if (is_utf8) {
+ count += utf8_prefix_size;
+ }
+
/* watch for buffer overflow */
if ((reqp->mp - reqp->data) + count > sizeof(reqp->data)) {
if ( IoctlDebug() )
return -1;
}
+ if (is_utf8) {
+ memcpy(reqp->mp, utf8_prefix, utf8_prefix_size);
+ reqp->mp += utf8_prefix_size;
+ count -= utf8_prefix_size;
+ }
+
if (stringp)
memcpy(reqp->mp, stringp, count);
else
return 0;
}
-long
-pioctl(char *pathp, long opcode, struct ViceIoctl *blobp, int follow)
+static long
+pioctl_int(char *pathp, long opcode, struct ViceIoctl *blobp, int follow, int is_utf8)
{
fs_ioctlRequest_t preq;
long code;
strcpy(fullPath, "");
}
- MarshallString(&preq, fullPath);
+ MarshallString(&preq, fullPath, is_utf8);
if (blobp->in_size) {
if (blobp->in_size > sizeof(preq.data) - (preq.mp - preq.data)*sizeof(char)) {
errno = E2BIG;
CloseHandle(reqHandle);
return 0;
}
+
+long
+pioctl_utf8(char * pathp, long opcode, struct ViceIoctl * blobp, int follow)
+{
+ return pioctl_int(pathp, opcode, blobp, follow, TRUE);
+}
+
+long
+pioctl(char * pathp, long opcode, struct ViceIoctl * blobp, int follow)
+{
+ return pioctl_int(pathp, opcode, blobp, follow, FALSE);
+}
+
extern long pioctl(char *pathp, long opcode, struct ViceIoctl *blob,
int follow);
+extern long pioctl_utf8(char *pathp, long opcode, struct ViceIoctl *blob,
+ int follow);
+
#endif /* OPENAFS_AFS_PIOCTL_H */