KDFS-windows-unicode-support-20080509

LICENSE MIT

This delta provides a fairly complete implementation of Unicode character
set support for the Windows Cache Manager and supporting tools including
fs.exe, symlink.exe, the pioctl library, and the explorer shell extension.

New Build requirements:

In order to build the Microsoft IDN Mitigation APIs SDK 1.1 is now required.
This SDK provides the normalization.h header and the redistribution
install packages required to install normaliz.dll.   The AFSDEV_INCLUDE
path must be modified to point to the directory containing normalization.h.
There are no lib files for this package.

Cache Manager:

The CM SMB server has been modified to negotiate the use of UNICODE.
By default it is on.  The "fs smbunicode" command can be used to disable
UNICODE at runtime.

cm_utils now contains UNICODE normalization and conversion routines built
on top of the IDN Mitigation APIs.

All input strings are normalized with UNICODE Normalization Form C.

The pioctl interface now supports UTF8 strings in addition to ANSI.
UTF8 strings are prefixed with <ESC> % 8 as per the ISO 2022 extension.


Pioctl Library:

New apps should use the pioctl_utf8() function instead of pioctl().
pioctl() is for ANSI strings and provides backward compatibility
with third party apps.

fs.exe and symlink.exe:

Converted to Unicode applications.  All strings are now communicated
using UTF-8.

Explorer Shell Extension:

Converted to a Unicode DLL.  All strings are now communicated using
UTF-8.  Fonts on U.S. Windows distributions are not fully populated.
As a result not all of the characters can be displayed in all of the
dialog boxes.

Still to do:

1. Add Unicode normalization to AFS directory entries and mountpoint
   and symlink target strings.

2. Use the Unicode version of GetCurrentDirectory in fs_utils.c

3. Update the installers to install the IDN Mitigation APIs on XP
   and 2003.  Vista already has them and they are not supported on
   pre XP SP2 releases.


(cherry picked from commit a36ec90cff608c3805f524070eb21aacc118f9e2)
This commit is contained in:
Asanka Herath 2008-05-09 15:59:41 +00:00 committed by Jeffrey Altman
parent e6a3821512
commit 565d02f889
37 changed files with 2488 additions and 1261 deletions

View File

@ -58,10 +58,12 @@ versions are supported:
Microsoft Visual Studio .NET 2003 Microsoft Visual Studio .NET 2003
available via a MSDN subscription available via a MSDN subscription
Microsoft Visual Studio .NET 2005 (required for AMD64 builds) Microsoft Visual Studio .NET 2005
available via a MSDN subscription available via a MSDN subscription
(recommended - required for 64-bit builds) (recommended - required for 64-bit builds)
Microsoft Visual Studio 2008 is not supported
The following Microsoft SDK is required: The following Microsoft SDK is required:
Microsoft Platform SDK for Windows XP SP2 or Server 2003 SP1 or Vista Microsoft Platform SDK for Windows XP SP2 or Server 2003 SP1 or Vista
@ -78,6 +80,10 @@ The Microsoft HTML Help Workshop is required:
http://www.microsoft.com/downloads/details.aspx?familyid=00535334-c8a6-452f-9aa0-d597d16580cc&displaylang=en 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 The NSIS installer requires about 14 MB of storage. The following
version is supported: version is supported:
@ -174,6 +180,7 @@ The header files that are required from a Microsoft SDK/DDK are:
npapi.h (Windows 2000,XP,2003 builds) npapi.h (Windows 2000,XP,2003 builds)
netcfgx.h (NSIS Loopback Adapter installer - 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) 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: These files come from the following Microsoft DDKs/SDKs:
@ -184,6 +191,9 @@ These files come from the following Microsoft DDKs/SDKs:
Windows XP/2003 DDK - inc/wxp/ Windows XP/2003 DDK - inc/wxp/
normalization.h:
Microsoft IDN Mitigation APIs 1.1 - include/
STEP D. Configure NTBUILD.BAT. STEP D. Configure NTBUILD.BAT.
The NTBUILD.BAT file copied to the OpenAFS base directory must be The NTBUILD.BAT file copied to the OpenAFS base directory must be

View File

@ -5,7 +5,7 @@
# License. For details, see the LICENSE file in the top-level source # License. For details, see the LICENSE file in the top-level source
# directory or online at http://www.openafs.org/dl/license10.html # 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 -I..\afsrdr\common -I..\afsrdr\user -IC:\winddk\IFSKit\inc\wnet AFSDEV_AUXCDEFINES = $(AFSDEV_AUXCDEFINES) /D"_AFXDLL" /DSMB_UNICODE -I..\kfw\inc\loadfuncs -I..\kfw\inc\krb5 -I..\kfw\inc\leash -I..\afsrdr\common -I..\afsrdr\user -IC:\winddk\IFSKit\inc\wnet
AFSDEV_NETGUI = 1 AFSDEV_NETGUI = 1
RELDIR=WINNT\afsd RELDIR=WINNT\afsd

View File

@ -995,6 +995,15 @@ int afsd_InitCM(char **reasonP)
} }
#endif /* AFS_FREELANCE_CLIENT */ #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); dummyLen = sizeof(smb_hideDotFiles);
code = RegQueryValueEx(parmKey, "HideDotFiles", NULL, NULL, code = RegQueryValueEx(parmKey, "HideDotFiles", NULL, NULL,
(BYTE *) &smb_hideDotFiles, &dummyLen); (BYTE *) &smb_hideDotFiles, &dummyLen);
@ -1243,6 +1252,8 @@ int afsd_InitCM(char **reasonP)
cm_InitCallback(); cm_InitCallback();
cm_InitNormalization();
code = cm_InitMappedMemory(virtualCache, cm_CachePath, stats, volumes, cells, cm_chunkSize, cacheBlocks, blockSize); code = cm_InitMappedMemory(virtualCache, cm_CachePath, stats, volumes, cells, cm_chunkSize, cacheBlocks, blockSize);
afsi_log("cm_InitMappedMemory code %x", code); afsi_log("cm_InitMappedMemory code %x", code);
if (code != 0) { if (code != 0) {
@ -1776,7 +1787,9 @@ LONG __stdcall afsd_ExceptionFilter(EXCEPTION_POINTERS *ep)
void afsd_SetUnhandledExceptionFilter() void afsd_SetUnhandledExceptionFilter()
{ {
#ifndef NOTRACE
SetUnhandledExceptionFilter(afsd_ExceptionFilter); SetUnhandledExceptionFilter(afsd_ExceptionFilter);
#endif
} }
#ifdef _DEBUG #ifdef _DEBUG

View File

@ -45,6 +45,9 @@
#define PIOCTL_LOGON 0x1 #define PIOCTL_LOGON 0x1
#define MAX_PATH 260 #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; osi_mutex_t cm_Afsdsbmt_Lock;
extern afs_int32 cryptall; extern afs_int32 cryptall;
@ -199,6 +202,7 @@ long cm_ParseIoctlPath(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp,
char * relativePath; char * relativePath;
char * lastComponent = NULL; char * lastComponent = NULL;
afs_uint32 follow = (flags & CM_PARSE_FLAG_LITERAL ? CM_FLAG_NOMOUNTCHASE : CM_FLAG_FOLLOW); afs_uint32 follow = (flags & CM_PARSE_FLAG_LITERAL ? CM_FLAG_NOMOUNTCHASE : CM_FLAG_FOLLOW);
int free_path = FALSE;
relativePath = ioctlp->inDatap; relativePath = ioctlp->inDatap;
/* setup the next data value for the caller to use */ /* setup the next data value for the caller to use */
@ -219,11 +223,47 @@ long cm_ParseIoctlPath(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp,
* file system API. Therefore, they are not OEM characters but * file system API. Therefore, they are not OEM characters but
* whatever the display character set is. * whatever the display character set is.
*/ */
// TranslateExtendedChars(relativePath); // TranslateExtendedChars(relativePath);
/* This is usually nothing, but for StatMountPoint it is the file name. */ /* This is usually nothing, but for StatMountPoint it is the file name. */
// TranslateExtendedChars(ioctlp->inDatap); // 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] && if (relativePath[0] == relativePath[1] &&
relativePath[1] == '\\' && relativePath[1] == '\\' &&
!_strnicmp(cm_NetbiosName,relativePath+2,strlen(cm_NetbiosName))) !_strnicmp(cm_NetbiosName,relativePath+2,strlen(cm_NetbiosName)))
@ -257,6 +297,8 @@ long cm_ParseIoctlPath(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp,
free(sharePath); free(sharePath);
if (code) { if (code) {
osi_Log1(afsd_logp,"cm_ParseIoctlPath [1] code 0x%x", code); osi_Log1(afsd_logp,"cm_ParseIoctlPath [1] code 0x%x", code);
if (free_path)
free(relativePath);
return code; return code;
} }
@ -279,6 +321,8 @@ long cm_ParseIoctlPath(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp,
cm_ReleaseSCache(substRootp); cm_ReleaseSCache(substRootp);
if (code) { if (code) {
osi_Log1(afsd_logp,"cm_ParseIoctlPath [2] code 0x%x", code); osi_Log1(afsd_logp,"cm_ParseIoctlPath [2] code 0x%x", code);
if (free_path)
free(relativePath);
return code; return code;
} }
} else { } else {
@ -304,6 +348,8 @@ long cm_ParseIoctlPath(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp,
userp, shareName, reqp, &substRootp); userp, shareName, reqp, &substRootp);
if (code) { if (code) {
osi_Log1(afsd_logp,"cm_ParseIoctlPath [3] code 0x%x", code); osi_Log1(afsd_logp,"cm_ParseIoctlPath [3] code 0x%x", code);
if (free_path)
free(relativePath);
return code; return code;
} }
@ -327,6 +373,8 @@ long cm_ParseIoctlPath(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp,
if (code) { if (code) {
cm_ReleaseSCache(substRootp); cm_ReleaseSCache(substRootp);
osi_Log1(afsd_logp,"cm_ParseIoctlPath code [4] 0x%x", code); osi_Log1(afsd_logp,"cm_ParseIoctlPath code [4] 0x%x", code);
if (free_path)
free(relativePath);
return code; return code;
} }
} }
@ -336,6 +384,8 @@ long cm_ParseIoctlPath(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp,
userp, ioctlp->tidPathp, reqp, &substRootp); userp, ioctlp->tidPathp, reqp, &substRootp);
if (code) { if (code) {
osi_Log1(afsd_logp,"cm_ParseIoctlPath [6] code 0x%x", code); osi_Log1(afsd_logp,"cm_ParseIoctlPath [6] code 0x%x", code);
if (free_path)
free(relativePath);
return code; return code;
} }
@ -358,6 +408,8 @@ long cm_ParseIoctlPath(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp,
if (code) { if (code) {
cm_ReleaseSCache(substRootp); cm_ReleaseSCache(substRootp);
osi_Log1(afsd_logp,"cm_ParseIoctlPath [7] code 0x%x", code); osi_Log1(afsd_logp,"cm_ParseIoctlPath [7] code 0x%x", code);
if (free_path)
free(relativePath);
return code; return code;
} }
} }
@ -367,6 +419,9 @@ long cm_ParseIoctlPath(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp,
/* and return success */ /* and return success */
osi_Log1(afsd_logp,"cm_ParseIoctlPath [8] code 0x%x", code); osi_Log1(afsd_logp,"cm_ParseIoctlPath [8] code 0x%x", code);
if (free_path)
free(relativePath);
return 0; return 0;
} }
@ -458,8 +513,47 @@ long cm_ParseIoctlParent(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp,
char tbuffer[1024]; char tbuffer[1024];
char *tp, *jp; char *tp, *jp;
cm_scache_t *substRootp = NULL; cm_scache_t *substRootp = NULL;
char *inpathp;
int free_path = FALSE;
StringCbCopyA(tbuffer, sizeof(tbuffer), ioctlp->inDatap); 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.*/
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, '\\'); tp = strrchr(tbuffer, '\\');
jp = strrchr(tbuffer, '/'); jp = strrchr(tbuffer, '/');
if (!tp) if (!tp)
@ -469,7 +563,7 @@ long cm_ParseIoctlParent(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp,
if (!tp) { if (!tp) {
StringCbCopyA(tbuffer, sizeof(tbuffer), "\\"); StringCbCopyA(tbuffer, sizeof(tbuffer), "\\");
if (leafp) if (leafp)
StringCbCopyA(leafp, LEAF_SIZE, ioctlp->inDatap); StringCbCopyA(leafp, LEAF_SIZE, inpathp);
} }
else { else {
*tp = 0; *tp = 0;
@ -477,6 +571,10 @@ long cm_ParseIoctlParent(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp,
StringCbCopyA(leafp, LEAF_SIZE, tp+1); 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] && if (tbuffer[0] == tbuffer[1] &&
tbuffer[1] == '\\' && tbuffer[1] == '\\' &&
!_strnicmp(cm_NetbiosName,tbuffer+2,strlen(cm_NetbiosName))) !_strnicmp(cm_NetbiosName,tbuffer+2,strlen(cm_NetbiosName)))
@ -847,6 +945,7 @@ long cm_IoctlSetVolumeStatus(struct smb_ioctl *ioctlp, struct cm_user *userp)
cm_cell_t *cellp; cm_cell_t *cellp;
cm_req_t req; cm_req_t req;
struct rx_connection * callp; struct rx_connection * callp;
int len;
cm_InitReq(&req); cm_InitReq(&req);
@ -879,11 +978,17 @@ long cm_IoctlSetVolumeStatus(struct smb_ioctl *ioctlp, struct cm_user *userp)
cp = ioctlp->inDatap; cp = ioctlp->inDatap;
memcpy((char *)&volStat, cp, sizeof(AFSFetchVolumeStatus)); memcpy((char *)&volStat, cp, sizeof(AFSFetchVolumeStatus));
cp += sizeof(AFSFetchVolumeStatus); cp += sizeof(AFSFetchVolumeStatus);
StringCbCopyA(volName, sizeof(volName), cp);
cp += strlen(volName)+1; len = strlen(cp) + 1;
StringCbCopyA(offLineMsg, sizeof(offLineMsg), cp); cm_NormalizeUtf8String(cp, len, volName, sizeof(volName));
cp += strlen(offLineMsg)+1; cp += len;
StringCbCopyA(motd, sizeof(motd), cp);
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; storeStat.Mask = 0;
if (volStat.MinQuota != -1) { if (volStat.MinQuota != -1) {
storeStat.MinQuota = volStat.MinQuota; storeStat.MinQuota = volStat.MinQuota;
@ -1906,7 +2011,9 @@ long cm_IoctlCreateMountPoint(struct smb_ioctl *ioctlp, struct cm_user *userp)
return code; return code;
/* Translate chars for the mount point name */ /* Translate chars for the mount point name */
if (!(ioctlp->flags & SMB_IOCTLFLAG_USEUTF8)) {
TranslateExtendedChars(leaf); TranslateExtendedChars(leaf);
}
/* /*
* The fs command allows the user to specify partial cell names on NT. These must * The fs command allows the user to specify partial cell names on NT. These must
@ -1975,19 +2082,45 @@ long cm_IoctlSymlink(struct smb_ioctl *ioctlp, struct cm_user *userp)
cm_attr_t tattr; cm_attr_t tattr;
char *cp; char *cp;
cm_req_t req; cm_req_t req;
char *symlp;
int free_syml = FALSE;
cm_InitReq(&req); cm_InitReq(&req);
code = cm_ParseIoctlParent(ioctlp, userp, &req, &dscp, leaf); code = cm_ParseIoctlParent(ioctlp, userp, &req, &dscp, leaf);
if (code) return code; if (code) return code;
if (!(ioctlp->flags & SMB_IOCTLFLAG_USEUTF8)) {
/* Translate chars for the link name */ /* Translate chars for the link name */
TranslateExtendedChars(leaf); TranslateExtendedChars(leaf);
/* Translate chars for the linked to name */ /* Translate chars for the linked to name */
TranslateExtendedChars(ioctlp->inDatap); TranslateExtendedChars(ioctlp->inDatap);
}
cp = ioctlp->inDatap; /* contents of link */ symlp = ioctlp->inDatap; /* contents of link */
{
char * normalized;
int normalized_len;
int len = strlen(symlp) + 1;
normalized_len = cm_NormalizeUtf8String(symlp, len, NULL, 0);
if (normalized_len > len) {
normalized = malloc(normalized_len);
free_syml = TRUE;
} else {
normalized = symlp;
}
cm_NormalizeUtf8String(symlp, len, normalized, normalized_len);
if (symlp != normalized)
symlp = normalized;
}
cp = symlp;
#ifdef AFS_FREELANCE_CLIENT #ifdef AFS_FREELANCE_CLIENT
if (cm_freelanceEnabled && dscp == cm_data.rootSCachep) { if (cm_freelanceEnabled && dscp == cm_data.rootSCachep) {
@ -2023,6 +2156,9 @@ long cm_IoctlSymlink(struct smb_ioctl *ioctlp, struct cm_user *userp)
cm_ReleaseSCache(dscp); cm_ReleaseSCache(dscp);
if (free_syml)
free(symlp);
return code; return code;
} }
@ -2891,11 +3027,43 @@ long cm_IoctlGetSMBName(smb_ioctl_t *ioctlp, cm_user_t *userp)
return 0; 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 cm_IoctlUUIDControl(struct smb_ioctl * ioctlp, struct cm_user *userp)
{ {
long cmd; long cmd;
afsUUID uuid; afsUUID uuid;
cm_SkipIoctlPath(ioctlp);
memcpy(&cmd, ioctlp->inDatap, sizeof(long)); memcpy(&cmd, ioctlp->inDatap, sizeof(long));
if (cmd) { /* generate a new UUID */ if (cmd) { /* generate a new UUID */
@ -2910,6 +3078,8 @@ long cm_IoctlUUIDControl(struct smb_ioctl * ioctlp, struct cm_user *userp)
return 0; return 0;
} }
/* /*
* functions to dump contents of various structures. * functions to dump contents of various structures.
* In debug build (linked with crt debug library) will dump allocated but not freed memory * In debug build (linked with crt debug library) will dump allocated but not freed memory
@ -3119,7 +3289,6 @@ long cm_IoctlVolStatTest(struct smb_ioctl *ioctlp, struct cm_user *userp)
struct VolStatTest * testp; struct VolStatTest * testp;
cm_req_t req; cm_req_t req;
afs_uint32 n; afs_uint32 n;
size_t len;
cm_InitReq(&req); cm_InitReq(&req);

View File

@ -100,6 +100,12 @@ extern char * cm_sysName;
extern unsigned int cm_sysNameCount; extern unsigned int cm_sysNameCount;
extern char * cm_sysNameList[MAXNUMSYSNAMES]; 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 */ /* flags for rxstats pioctl */
#define AFSCALL_RXSTATS_MASK 0x7 /* Valid flag bits */ #define AFSCALL_RXSTATS_MASK 0x7 /* Valid flag bits */
@ -223,6 +229,8 @@ extern long cm_IoctlGetFileType(smb_ioctl_t *ioctlp, cm_user_t *userp);
extern long cm_IoctlVolStatTest(struct smb_ioctl *ioctlp, struct cm_user *userp); 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_INTERFACES_ONLY__ */
#endif /* __CM_IOCTL_H_ENV__ */ #endif /* __CM_IOCTL_H_ENV__ */

View File

@ -69,6 +69,9 @@
#include <osi.h> #include <osi.h>
#include <rx/rx.h> #include <rx/rx.h>
#define STRSAFE_NO_DEPRECATE
#include <strsafe.h>
static osi_once_t cm_utilsOnce; static osi_once_t cm_utilsOnce;
@ -359,3 +362,276 @@ void cm_FreeSpace(cm_space_t *tsp)
cm_spaceListp = tsp; cm_spaceListp = tsp;
lock_ReleaseWrite(&cm_utilsLock); 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;
}

View File

@ -28,4 +28,9 @@ extern long cm_MapRPCError(long error, cm_req_t *reqp);
extern long cm_MapRPCErrorRmdir(long error, cm_req_t *reqp); extern long cm_MapRPCErrorRmdir(long error, cm_req_t *reqp);
extern long cm_MapVLRPCError(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__ */ #endif /* __CM_UTILS_H_ENV__ */

View File

@ -251,7 +251,7 @@ InAFS(char *apath)
blob.out_size = MAXSIZE; blob.out_size = MAXSIZE;
blob.out = space; 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 (code) {
if ((errno == EINVAL) || (errno == ENOENT)) if ((errno == EINVAL) || (errno == ENOENT))
return 0; return 0;
@ -269,7 +269,7 @@ IsFreelanceRoot(char *apath)
blob.out_size = MAXSIZE; blob.out_size = MAXSIZE;
blob.out = space; 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) if (code == 0)
return !stricmp("Freelance.Local.Root",space); return !stricmp("Freelance.Local.Root",space);
return 1; /* assume it is because it is more restrictive that way */ return 1; /* assume it is because it is more restrictive that way */
@ -612,7 +612,6 @@ ParseAcl (char *astr)
} }
ta->minuslist = first; ta->minuslist = first;
exit:
return ta; return ta;
nminus_err: nminus_err:
@ -929,7 +928,7 @@ SetACLCmd(struct cmd_syndesc *as, void *arock)
blob.out_size = MAXSIZE; blob.out_size = MAXSIZE;
blob.in_size = idf; blob.in_size = idf;
blob.in = blob.out = space; blob.in = blob.out = space;
code = pioctl(ti->data, VIOCGETAL, &blob, 1); code = pioctl_utf8(ti->data, VIOCGETAL, &blob, 1);
if (code) { if (code) {
Die(errno, ti->data); Die(errno, ti->data);
error = 1; error = 1;
@ -992,7 +991,7 @@ SetACLCmd(struct cmd_syndesc *as, void *arock)
blob.in = AclToString(ta); blob.in = AclToString(ta);
blob.out_size=0; blob.out_size=0;
blob.in_size = 1+(long)strlen(blob.in); 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 (code) {
if (errno == EINVAL) { if (errno == EINVAL) {
if (ta->dfs) { if (ta->dfs) {
@ -1069,7 +1068,7 @@ CopyACLCmd(struct cmd_syndesc *as, void *arock)
blob.out_size = MAXSIZE; blob.out_size = MAXSIZE;
blob.in_size = idf; blob.in_size = idf;
blob.in = blob.out = space; 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) { if (code) {
Die(errno, as->parms[0].items->data); Die(errno, as->parms[0].items->data);
return 1; return 1;
@ -1086,7 +1085,7 @@ CopyACLCmd(struct cmd_syndesc *as, void *arock)
blob.out_size = MAXSIZE; blob.out_size = MAXSIZE;
blob.in_size = idf; blob.in_size = idf;
blob.in = blob.out = space; blob.in = blob.out = space;
code = pioctl(ti->data, VIOCGETAL, &blob, 1); code = pioctl_utf8(ti->data, VIOCGETAL, &blob, 1);
if (code) { if (code) {
Die(errno, ti->data); Die(errno, ti->data);
error = 1; error = 1;
@ -1130,7 +1129,7 @@ CopyACLCmd(struct cmd_syndesc *as, void *arock)
blob.in = AclToString(ta); blob.in = AclToString(ta);
blob.out_size=0; blob.out_size=0;
blob.in_size = 1+(long)strlen(blob.in); 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 (code) {
if (errno == EINVAL) { if (errno == EINVAL) {
fprintf(stderr, fprintf(stderr,
@ -1148,7 +1147,7 @@ CopyACLCmd(struct cmd_syndesc *as, void *arock)
return error; return error;
} }
/* pioctl() call to get the cellname of a pathname */ /* pioctl_utf8() call to get the cellname of a pathname */
static afs_int32 static afs_int32
GetCell(char *fname, char *cellname) GetCell(char *fname, char *cellname)
{ {
@ -1159,7 +1158,7 @@ GetCell(char *fname, char *cellname)
blob.out_size = MAXCELLCHARS; blob.out_size = MAXCELLCHARS;
blob.out = cellname; blob.out = cellname;
code = pioctl(fname, VIOC_FILE_CELL_NAME, &blob, 1); code = pioctl_utf8(fname, VIOC_FILE_CELL_NAME, &blob, 1);
return code; return code;
} }
@ -1258,7 +1257,7 @@ CleanACLCmd(struct cmd_syndesc *as, void *arock)
blob.out_size = MAXSIZE; blob.out_size = MAXSIZE;
blob.in_size = 0; blob.in_size = 0;
blob.out = space; blob.out = space;
code = pioctl(ti->data, VIOCGETAL, &blob, 1); code = pioctl_utf8(ti->data, VIOCGETAL, &blob, 1);
if (code) { if (code) {
Die(errno, ti->data); Die(errno, ti->data);
error = 1; error = 1;
@ -1289,7 +1288,7 @@ CleanACLCmd(struct cmd_syndesc *as, void *arock)
blob.in=AclToString(ta); blob.in=AclToString(ta);
blob.in_size = (long)strlen(blob.in)+1; blob.in_size = (long)strlen(blob.in)+1;
blob.out_size = 0; blob.out_size = 0;
code = pioctl(ti->data, VIOCSETAL, &blob, 1); code = pioctl_utf8(ti->data, VIOCSETAL, &blob, 1);
if (code) { if (code) {
if (errno == EINVAL) { if (errno == EINVAL) {
fprintf(stderr, fprintf(stderr,
@ -1352,7 +1351,7 @@ ListACLCmd(struct cmd_syndesc *as, void *arock)
blob.out_size = MAXSIZE; blob.out_size = MAXSIZE;
blob.in_size = idf; blob.in_size = idf;
blob.in = blob.out = space; blob.in = blob.out = space;
code = pioctl(ti->data, VIOCGETAL, &blob, 1); code = pioctl_utf8(ti->data, VIOCGETAL, &blob, 1);
if (code) { if (code) {
Die(errno, ti->data); Die(errno, ti->data);
error = 1; error = 1;
@ -1415,7 +1414,7 @@ FlushAllCmd(struct cmd_syndesc *as, void *arock)
struct ViceIoctl blob; struct ViceIoctl blob;
blob.in_size = blob.out_size = 0; blob.in_size = blob.out_size = 0;
code = pioctl(NULL, VIOC_FLUSHALL, &blob, 0); code = pioctl_utf8(NULL, VIOC_FLUSHALL, &blob, 0);
if (code) { if (code) {
fprintf(stderr, "Error flushing all "); fprintf(stderr, "Error flushing all ");
return 1; return 1;
@ -1434,7 +1433,7 @@ FlushVolumeCmd(struct cmd_syndesc *as, void *arock)
SetDotDefault(&as->parms[0].items); SetDotDefault(&as->parms[0].items);
for(ti=as->parms[0].items; ti; ti=ti->next) { for(ti=as->parms[0].items; ti; ti=ti->next) {
blob.in_size = blob.out_size = 0; 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) { if (code) {
fprintf(stderr, "Error flushing volume "); fprintf(stderr, "Error flushing volume ");
perror(ti->data); perror(ti->data);
@ -1468,7 +1467,7 @@ FlushCmd(struct cmd_syndesc *as, void *arock)
blob.in = &options; blob.in = &options;
blob.out_size = 0; blob.out_size = 0;
code = pioctl(ti->data, VIOCFLUSH, &blob, 0); code = pioctl_utf8(ti->data, VIOCFLUSH, &blob, 0);
if (code) { if (code) {
if (errno == EMFILE) { if (errno == EMFILE) {
fprintf(stderr, "%s: Can't flush active file %s\n", pn, fprintf(stderr, "%s: Can't flush active file %s\n", pn,
@ -1550,7 +1549,7 @@ SetVolCmd(struct cmd_syndesc *as, void *arock) {
input += strlen(motd) + 1; input += strlen(motd) + 1;
} else } else
*(input++) = '\0'; *(input++) = '\0';
code = pioctl(ti->data,VIOCSETVOLSTAT, &blob, 1); code = pioctl_utf8(ti->data,VIOCSETVOLSTAT, &blob, 1);
if (code) { if (code) {
Die(errno, ti->data); Die(errno, ti->data);
error = 1; error = 1;
@ -1619,7 +1618,7 @@ ExamineCmd(struct cmd_syndesc *as, void *arock)
blob.out_size = sizeof(cm_fid_t); blob.out_size = sizeof(cm_fid_t);
blob.out = (char *) &fid; 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.field_flags |= CM_IOCTL_QOPTS_FIELD_FID;
options.fid = fid; options.fid = fid;
} else { } else {
@ -1631,12 +1630,12 @@ ExamineCmd(struct cmd_syndesc *as, void *arock)
blob.out_size = sizeof(filetype); blob.out_size = sizeof(filetype);
blob.out = &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_size = MAXCELLCHARS;
blob.out = cell; 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", printf("%s %s (%u.%u.%u) contained in cell %s\n",
filetypestr(filetype), filetypestr(filetype),
ti->data, fid.volume, fid.vnode, fid.unique, ti->data, fid.volume, fid.vnode, fid.unique,
@ -1644,7 +1643,7 @@ ExamineCmd(struct cmd_syndesc *as, void *arock)
blob.out_size = 2 * sizeof(afs_uint32); blob.out_size = 2 * sizeof(afs_uint32);
blob.out = (char *) &owner; 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 oname[PR_MAXNAMELEN] = "(unknown)";
char confDir[257]; char confDir[257];
@ -1658,7 +1657,7 @@ ExamineCmd(struct cmd_syndesc *as, void *arock)
blob.out = space; blob.out = space;
blob.out_size = MAXSIZE; blob.out_size = MAXSIZE;
code = pioctl(ti->data, VIOCGETVOLSTAT, &blob, 1); code = pioctl_utf8(ti->data, VIOCGETVOLSTAT, &blob, 1);
if (code == 0) { if (code == 0) {
status = (VolumeStatus *)space; status = (VolumeStatus *)space;
name = (char *)status + sizeof(*status); name = (char *)status + sizeof(*status);
@ -1671,7 +1670,7 @@ ExamineCmd(struct cmd_syndesc *as, void *arock)
} }
errno = 0; errno = 0;
code = pioctl(ti->data, VIOC_PATH_AVAILABILITY, &blob, 1); code = pioctl_utf8(ti->data, VIOC_PATH_AVAILABILITY, &blob, 1);
switch (errno) { switch (errno) {
case 0: case 0:
printf("Volume is online\n"); printf("Volume is online\n");
@ -1713,7 +1712,7 @@ ListQuotaCmd(struct cmd_syndesc *as, void *arock)
blob.out_size = MAXSIZE; blob.out_size = MAXSIZE;
blob.in_size = 0; blob.in_size = 0;
blob.out = space; blob.out = space;
code = pioctl(ti->data, VIOCGETVOLSTAT, &blob, 1); code = pioctl_utf8(ti->data, VIOCGETVOLSTAT, &blob, 1);
if (code) { if (code) {
Die(errno, ti->data); Die(errno, ti->data);
error = 1; error = 1;
@ -1759,7 +1758,7 @@ WhereIsCmd(struct cmd_syndesc *as, void *arock)
blob.out_size = sizeof(cm_fid_t); blob.out_size = sizeof(cm_fid_t);
blob.out = (char *) &fid; 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.field_flags |= CM_IOCTL_QOPTS_FIELD_FID;
options.fid = fid; options.fid = fid;
} else { } else {
@ -1771,12 +1770,12 @@ WhereIsCmd(struct cmd_syndesc *as, void *arock)
blob.out_size = sizeof(filetype); blob.out_size = sizeof(filetype);
blob.out = &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_size = MAXSIZE;
blob.out = space; blob.out = space;
memset(space, 0, sizeof(space)); memset(space, 0, sizeof(space));
code = pioctl(ti->data, VIOCWHEREIS, &blob, 1); code = pioctl_utf8(ti->data, VIOCWHEREIS, &blob, 1);
if (code) { if (code) {
Die(errno, ti->data); Die(errno, ti->data);
error = 1; error = 1;
@ -1817,7 +1816,7 @@ DiskFreeCmd(struct cmd_syndesc *as, void *arock)
blob.out_size = MAXSIZE; blob.out_size = MAXSIZE;
blob.in_size = 0; blob.in_size = 0;
blob.out = space; blob.out = space;
code = pioctl(ti->data, VIOCGETVOLSTAT, &blob, 1); code = pioctl_utf8(ti->data, VIOCGETVOLSTAT, &blob, 1);
if (code) { if (code) {
Die(errno, ti->data); Die(errno, ti->data);
error = 1; error = 1;
@ -1846,7 +1845,7 @@ QuotaCmd(struct cmd_syndesc *as, void *arock)
blob.out_size = MAXSIZE; blob.out_size = MAXSIZE;
blob.in_size = 0; blob.in_size = 0;
blob.out = space; blob.out = space;
code = pioctl(ti->data, VIOCGETVOLSTAT, &blob, 1); code = pioctl_utf8(ti->data, VIOCGETVOLSTAT, &blob, 1);
if (code) { if (code) {
Die(errno, ti->data); Die(errno, ti->data);
error = 1; error = 1;
@ -1994,7 +1993,7 @@ ListMountCmd(struct cmd_syndesc *as, void *arock)
blob.out = space; blob.out = space;
memset(space, 0, MAXSIZE); 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) { if (code == 0) {
printf("'%s' is a %smount point for volume '%s'\n", printf("'%s' is a %smount point for volume '%s'\n",
@ -2091,7 +2090,7 @@ MakeMountCmd(struct cmd_syndesc *as, void *arock)
blob.in_size = 0; blob.in_size = 0;
blob.out_size = sizeof(localCellName); blob.out_size = sizeof(localCellName);
blob.out = 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) if (!code)
cellName = localCellName; cellName = localCellName;
} }
@ -2142,7 +2141,7 @@ MakeMountCmd(struct cmd_syndesc *as, void *arock)
blob.in_size = 1 + (long)strlen(space); blob.in_size = 1 + (long)strlen(space);
blob.in = space; blob.in = space;
blob.out = NULL; 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 */ #else /* not WIN32 */
code = symlink(space, path); code = symlink(space, path);
#endif /* not WIN32 */ #endif /* not WIN32 */
@ -2203,7 +2202,7 @@ RemoveMountCmd(struct cmd_syndesc *as, void *arock) {
blob.in_size = (long)strlen(tp)+1; blob.in_size = (long)strlen(tp)+1;
blob.out = lsbuffer; blob.out = lsbuffer;
blob.out_size = sizeof(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 (code) {
if (errno == EINVAL) { if (errno == EINVAL) {
fprintf(stderr,"%s: '%s' is not a mount point.\n", pn, ti->data); fprintf(stderr,"%s: '%s' is not a mount point.\n", pn, ti->data);
@ -2223,7 +2222,7 @@ RemoveMountCmd(struct cmd_syndesc *as, void *arock) {
blob.out_size = 0; blob.out_size = 0;
blob.in = tp; blob.in = tp;
blob.in_size = (long)strlen(tp)+1; 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) { if (code) {
Die(errno, ti->data); Die(errno, ti->data);
error = 1; error = 1;
@ -2306,7 +2305,7 @@ CheckServersCmd(struct cmd_syndesc *as, void *arock)
#endif /* WIN32 */ #endif /* WIN32 */
} }
code = pioctl(0, VIOCCKSERV, &blob, 1); code = pioctl_utf8(0, VIOCCKSERV, &blob, 1);
if (code) { if (code) {
if ((errno == EACCES) && (checkserv.tinterval > 0)) { if ((errno == EACCES) && (checkserv.tinterval > 0)) {
printf("Must be root to change -interval\n"); printf("Must be root to change -interval\n");
@ -2376,7 +2375,7 @@ MessagesCmd(struct cmd_syndesc *as, void *arock)
if (code) if (code)
return 1; return 1;
code = pioctl(0, VIOC_GAG, &blob, 1); code = pioctl_utf8(0, VIOC_GAG, &blob, 1);
if (code) { if (code) {
Die(errno, 0); Die(errno, 0);
return 1; return 1;
@ -2392,7 +2391,7 @@ CheckVolumesCmd(struct cmd_syndesc *as, void *arock)
blob.in_size = 0; blob.in_size = 0;
blob.out_size = 0; blob.out_size = 0;
code = pioctl(0, VIOCCKBACK, &blob, 1); code = pioctl_utf8(0, VIOCCKBACK, &blob, 1);
if (code) { if (code) {
Die(errno, 0); Die(errno, 0);
return 1; return 1;
@ -2436,7 +2435,7 @@ SetCacheSizeCmd(struct cmd_syndesc *as, void *arock)
blob.in = (char *) &temp; blob.in = (char *) &temp;
blob.in_size = sizeof(afs_int32); blob.in_size = sizeof(afs_int32);
blob.out_size = 0; blob.out_size = 0;
code = pioctl(0, VIOCSETCACHESIZE, &blob, 1); code = pioctl_utf8(0, VIOCSETCACHESIZE, &blob, 1);
if (code) { if (code) {
Die(errno, (char *) 0); Die(errno, (char *) 0);
return 1; return 1;
@ -2458,7 +2457,7 @@ GetCacheParmsCmd(struct cmd_syndesc *as, void *arock)
blob.in_size = 0; blob.in_size = 0;
blob.out_size = sizeof(parms); blob.out_size = sizeof(parms);
blob.out = (char *) &parms; blob.out = (char *) &parms;
code = pioctl(0, VIOCGETCACHEPARMS, &blob, 1); code = pioctl_utf8(0, VIOCGETCACHEPARMS, &blob, 1);
if (code) { if (code) {
Die(errno, NULL); Die(errno, NULL);
return 1; return 1;
@ -2494,7 +2493,7 @@ ListCellsCmd(struct cmd_syndesc *as, void *arock)
blob.in_size = sizeof(afs_int32); blob.in_size = sizeof(afs_int32);
blob.in = space; blob.in = space;
blob.out = space; blob.out = space;
code = pioctl(0, VIOCGETCELL, &blob, 1); code = pioctl_utf8(0, VIOCGETCELL, &blob, 1);
if (code < 0) { if (code < 0) {
if (errno == EDOM) if (errno == EDOM)
break; /* done with the list */ break; /* done with the list */
@ -2545,7 +2544,7 @@ ListAliasesCmd(struct cmd_syndesc *as, void *arock)
blob.in_size = sizeof(afs_int32); blob.in_size = sizeof(afs_int32);
blob.in = space; blob.in = space;
blob.out = space; blob.out = space;
code = pioctl(0, VIOC_GETALIAS, &blob, 1); code = pioctl_utf8(0, VIOC_GETALIAS, &blob, 1);
if (code < 0) { if (code < 0) {
if (errno == EDOM) if (errno == EDOM)
break; /* done with the list */ break; /* done with the list */
@ -2592,7 +2591,7 @@ CallBackRxConnCmd(struct cmd_syndesc *as, void *arock)
blob.in = (char *) &hostAddr; blob.in = (char *) &hostAddr;
blob.out = (char *) &hostAddr; blob.out = (char *) &hostAddr;
code = pioctl(0, VIOC_CBADDR, &blob, 1); code = pioctl_utf8(0, VIOC_CBADDR, &blob, 1);
if (code < 0) { if (code < 0) {
Die(errno, 0); Die(errno, 0);
return 1; return 1;
@ -2667,7 +2666,7 @@ NewCellCmd(struct cmd_syndesc *as, void *arock)
blob.in_size = size; blob.in_size = size;
blob.in = space; blob.in = space;
blob.out_size = 0; blob.out_size = 0;
code = pioctl(0, VIOCNEWCELL, &blob, 1); code = pioctl_utf8(0, VIOCNEWCELL, &blob, 1);
if (code < 0) if (code < 0)
Die(errno, 0); Die(errno, 0);
return 0; return 0;
@ -2685,7 +2684,7 @@ NewCellCmd(struct cmd_syndesc *as, void *arock)
blob.out_size = MAXSIZE; blob.out_size = MAXSIZE;
blob.out = space; blob.out = space;
code = pioctl((char *) 0, VIOCNEWCELL, &blob, 1); code = pioctl_utf8((char *) 0, VIOCNEWCELL, &blob, 1);
if (code) { if (code) {
Die(errno, (char *) 0); Die(errno, (char *) 0);
@ -2719,7 +2718,7 @@ NewAliasCmd(struct cmd_syndesc *as, void *arock)
blob.in = space; blob.in = space;
blob.out_size = 0; blob.out_size = 0;
blob.out = space; blob.out = space;
code = pioctl(0, VIOC_NEWALIAS, &blob, 1); code = pioctl_utf8(0, VIOC_NEWALIAS, &blob, 1);
if (code < 0) { if (code < 0) {
if (errno == EEXIST) { if (errno == EEXIST) {
fprintf(stderr, fprintf(stderr,
@ -2765,7 +2764,7 @@ WhichCellCmd(struct cmd_syndesc *as, void *arock)
blob.out_size = sizeof(cm_fid_t); blob.out_size = sizeof(cm_fid_t);
blob.out = (char *) &fid; 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.field_flags |= CM_IOCTL_QOPTS_FIELD_FID;
options.fid = fid; options.fid = fid;
} else { } else {
@ -2777,12 +2776,12 @@ WhichCellCmd(struct cmd_syndesc *as, void *arock)
blob.out_size = sizeof(filetype); blob.out_size = sizeof(filetype);
blob.out = &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_size = MAXCELLCHARS;
blob.out = cell; 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 (code) {
if (errno == ENOENT) if (errno == ENOENT)
fprintf(stderr,"%s: no such cell as '%s'\n", pn, ti->data); fprintf(stderr,"%s: no such cell as '%s'\n", pn, ti->data);
@ -2809,7 +2808,7 @@ WSCellCmd(struct cmd_syndesc *as, void *arock)
blob.out_size = MAXSIZE; blob.out_size = MAXSIZE;
blob.out = space; blob.out = space;
code = pioctl(NULL, VIOC_GET_WS_CELL, &blob, 1); code = pioctl_utf8(NULL, VIOC_GET_WS_CELL, &blob, 1);
if (code) { if (code) {
Die(errno, NULL); Die(errno, NULL);
@ -2871,7 +2870,7 @@ MonitorCmd(struct cmd_syndesc *as, void *arock)
blob.out_size = sizeof(afs_int32); blob.out_size = sizeof(afs_int32);
blob.in = (char *) &hostAddr; blob.in = (char *) &hostAddr;
blob.out = (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) { if (code) {
Die(errno, 0); Die(errno, 0);
return 1; return 1;
@ -2934,7 +2933,7 @@ SysNameCmd(struct cmd_syndesc *as, void *arock)
*(input++) = '\0'; *(input++) = '\0';
} }
memcpy(space, &setp, sizeof(afs_int32)); 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) { if (code) {
Die(errno, 0); Die(errno, 0);
return 1; return 1;
@ -3040,7 +3039,7 @@ static int ExportAfsCmd(struct cmd_syndesc *as, void *arock)
blob.in_size = sizeof(afs_int32); blob.in_size = sizeof(afs_int32);
blob.out = (char *) &exportcall; blob.out = (char *) &exportcall;
blob.out_size = sizeof(afs_int32); blob.out_size = sizeof(afs_int32);
code = pioctl(0, VIOC_EXPORTAFS, &blob, 1); code = pioctl_utf8(0, VIOC_EXPORTAFS, &blob, 1);
if (code) { if (code) {
if (errno == ENODEV) { if (errno == ENODEV) {
fprintf(stderr, fprintf(stderr,
@ -3090,7 +3089,7 @@ GetCellCmd(struct cmd_syndesc *as, void *arock)
} }
blob.in_size = 1+(long)strlen(info.name); blob.in_size = 1+(long)strlen(info.name);
blob.in = info.name; blob.in = info.name;
code = pioctl(0, VIOC_GETCELLSTATUS, &blob, 1); code = pioctl_utf8(0, VIOC_GETCELLSTATUS, &blob, 1);
if (code) { if (code) {
if (errno == ENOENT) if (errno == ENOENT)
fprintf(stderr,"%s: the cell named '%s' does not exist\n", pn, info.name); fprintf(stderr,"%s: the cell named '%s' does not exist\n", pn, info.name);
@ -3166,7 +3165,7 @@ static int SetCellCmd(struct cmd_syndesc *as, void *arock)
blob.in = (caddr_t) &args; blob.in = (caddr_t) &args;
blob.out_size = 0; blob.out_size = 0;
blob.out = (caddr_t) 0; blob.out = (caddr_t) 0;
code = pioctl(0, VIOC_SETCELLSTATUS, &blob, 1); code = pioctl_utf8(0, VIOC_SETCELLSTATUS, &blob, 1);
if (code) { if (code) {
Die(errno, info.name); /* XXX added cell name to Die() call */ Die(errno, info.name); /* XXX added cell name to Die() call */
error = 1; error = 1;
@ -3218,7 +3217,7 @@ pokeServers(void)
{ {
int code; int code;
cm_SSetPref_t *ssp; cm_SSetPref_t *ssp;
code = pioctl(0, VIOC_SETSPREFS, &gblob, 1); code = pioctl_utf8(0, VIOC_SETSPREFS, &gblob, 1);
ssp = (cm_SSetPref_t *)space; ssp = (cm_SSetPref_t *)space;
gblob.in_size = (long)(((char *)&(ssp->servers[0])) - (char *)ssp); gblob.in_size = (long)(((char *)&(ssp->servers[0])) - (char *)ssp);
@ -3236,14 +3235,14 @@ pokeServers(void)
{ {
int code; int code;
code = pioctl(0, VIOC_SETSPREFS, &gblob, 1); code = pioctl_utf8(0, VIOC_SETSPREFS, &gblob, 1);
if (code && (errno == EINVAL)) { if (code && (errno == EINVAL)) {
struct setspref *ssp; struct setspref *ssp;
ssp = (struct setspref *)gblob.in; ssp = (struct setspref *)gblob.in;
if (!(ssp->flags & DBservers)) { if (!(ssp->flags & DBservers)) {
gblob.in = (void *)&(ssp->servers[0]); gblob.in = (void *)&(ssp->servers[0]);
gblob.in_size -= ((char *)&(ssp->servers[0])) - (char *)ssp; 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; return code ? errno : 0;
} }
fprintf(stderr, fprintf(stderr,
@ -3617,7 +3616,7 @@ GetPrefCmd(struct cmd_syndesc *as, void *arock)
in->num_servers = (MAXSIZE - 2*sizeof(short))/sizeof(struct cm_SPref); in->num_servers = (MAXSIZE - 2*sizeof(short))/sizeof(struct cm_SPref);
in->flags = vlservers; in->flags = vlservers;
code = pioctl(0, VIOC_GETSPREFS, &blob, 1); code = pioctl_utf8(0, VIOC_GETSPREFS, &blob, 1);
if (code){ if (code){
perror("getserverprefs pioctl"); perror("getserverprefs pioctl");
Die (errno,0); Die (errno,0);
@ -3689,7 +3688,7 @@ GetPrefCmd(struct cmd_syndesc *as, void *arock)
(MAXSIZE - 2 * sizeof(short)) / sizeof(struct spref); (MAXSIZE - 2 * sizeof(short)) / sizeof(struct spref);
in->flags = vlservers; in->flags = vlservers;
code = pioctl(0, VIOC_GETSPREFS, &blob, 1); code = pioctl_utf8(0, VIOC_GETSPREFS, &blob, 1);
if (code) { if (code) {
perror("getserverprefs pioctl"); perror("getserverprefs pioctl");
return 1; return 1;
@ -3716,6 +3715,52 @@ GetPrefCmd(struct cmd_syndesc *as, void *arock)
} }
#endif /* WIN32 */ #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 static int
UuidCmd(struct cmd_syndesc *asp, void *arock) UuidCmd(struct cmd_syndesc *asp, void *arock)
{ {
@ -3747,7 +3792,7 @@ UuidCmd(struct cmd_syndesc *asp, void *arock)
blob.out_size = sizeof(outValue); blob.out_size = sizeof(outValue);
blob.out = (char *) &outValue; blob.out = (char *) &outValue;
code = pioctl(NULL, VIOC_UUIDCTL, &blob, 1); code = pioctl_utf8(NULL, VIOC_UUIDCTL, &blob, 1);
if (code) { if (code) {
Die(errno, NULL); Die(errno, NULL);
return code; return code;
@ -3806,7 +3851,7 @@ TraceCmd(struct cmd_syndesc *asp, void *arock)
blob.out_size = sizeof(long); blob.out_size = sizeof(long);
blob.out = (char *) &outValue; blob.out = (char *) &outValue;
code = pioctl(NULL, VIOC_TRACECTL, &blob, 1); code = pioctl_utf8(NULL, VIOC_TRACECTL, &blob, 1);
if (code) { if (code) {
Die(errno, NULL); Die(errno, NULL);
return code; return code;
@ -3887,14 +3932,14 @@ StoreBehindCmd(struct cmd_syndesc *as, void *arock)
/* once per -file */ /* once per -file */
for (ti = as->parms[1].items; ti; ti = ti->next) { for (ti = as->parms[1].items; ti; ti = ti->next) {
/* Do this solely to see if the file is there */ /* 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) { if (code) {
Die(errno, ti->data); Die(errno, ti->data);
error = 1; error = 1;
continue; continue;
} }
code = pioctl(ti->data, VIOC_STOREBEHIND, &blob, 1); code = pioctl_utf8(ti->data, VIOC_STOREBEHIND, &blob, 1);
if (code) { if (code) {
Die(errno, ti->data); Die(errno, ti->data);
error = 1; error = 1;
@ -3918,7 +3963,7 @@ StoreBehindCmd(struct cmd_syndesc *as, void *arock)
*/ */
if (!as->parms[1].items || (allfiles != -1)) { if (!as->parms[1].items || (allfiles != -1)) {
tsb.sb_default = allfiles; tsb.sb_default = allfiles;
code = pioctl(0, VIOC_STOREBEHIND, &blob, 1); code = pioctl_utf8(0, VIOC_STOREBEHIND, &blob, 1);
if (code) { if (code) {
Die(errno, ((allfiles == -1) ? 0 : "-allfiles")); Die(errno, ((allfiles == -1) ? 0 : "-allfiles"));
error = 1; error = 1;
@ -3961,7 +4006,7 @@ SetCryptCmd(struct cmd_syndesc *as, void *arock)
blob.in = (char *) &flag; blob.in = (char *) &flag;
blob.in_size = sizeof(flag); blob.in_size = sizeof(flag);
blob.out_size = 0; blob.out_size = 0;
code = pioctl(0, VIOC_SETRXKCRYPT, &blob, 1); code = pioctl_utf8(0, VIOC_SETRXKCRYPT, &blob, 1);
if (code) if (code)
Die(code, NULL); Die(code, NULL);
return 0; return 0;
@ -3979,7 +4024,7 @@ GetCryptCmd(struct cmd_syndesc *as, void *arock)
blob.out_size = sizeof(flag); blob.out_size = sizeof(flag);
blob.out = space; blob.out = space;
code = pioctl(0, VIOC_GETRXKCRYPT, &blob, 1); code = pioctl_utf8(0, VIOC_GETRXKCRYPT, &blob, 1);
if (code) if (code)
Die(code, NULL); Die(code, NULL);
@ -4025,7 +4070,7 @@ MemDumpCmd(struct cmd_syndesc *asp, void *arock)
blob.out_size = sizeof(long); blob.out_size = sizeof(long);
blob.out = (char *) &outValue; blob.out = (char *) &outValue;
code = pioctl(NULL, VIOC_TRACEMEMDUMP, &blob, 1); code = pioctl_utf8(NULL, VIOC_TRACEMEMDUMP, &blob, 1);
if (code) { if (code) {
Die(errno, NULL); Die(errno, NULL);
return code; return code;
@ -4217,7 +4262,7 @@ GetClientAddrsCmd(struct cmd_syndesc *as, void *arock)
in->num_servers = in->num_servers =
(MAXSIZE - 2 * sizeof(short)) / sizeof(struct spref); (MAXSIZE - 2 * sizeof(short)) / sizeof(struct spref);
/* returns addr in network byte order */ /* returns addr in network byte order */
code = pioctl(0, VIOC_GETCPREFS, &blob, 1); code = pioctl_utf8(0, VIOC_GETCPREFS, &blob, 1);
if (code) { if (code) {
perror("getClientInterfaceAddr pioctl"); perror("getClientInterfaceAddr pioctl");
return 1; return 1;
@ -4306,7 +4351,7 @@ SetClientAddrsCmd(struct cmd_syndesc *as, void *arock)
} }
blob.in_size = sizeUsed - sizeof(struct spref); 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) { if (code) {
Die(errno, 0); Die(errno, 0);
error = 1; error = 1;
@ -4417,7 +4462,7 @@ FlushMountCmd(struct cmd_syndesc *as, void *arock)
blob.out_size = 0; blob.out_size = 0;
memset(space, 0, MAXSIZE); 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 (code != 0) {
if (errno == EINVAL) { if (errno == EINVAL) {
@ -4457,7 +4502,7 @@ RxStatProcCmd(struct cmd_syndesc *as, void *arock)
blob.in_size = sizeof(afs_int32); blob.in_size = sizeof(afs_int32);
blob.out_size = 0; blob.out_size = 0;
code = pioctl(NULL, VIOC_RXSTAT_PROC, &blob, 1); code = pioctl_utf8(NULL, VIOC_RXSTAT_PROC, &blob, 1);
if (code != 0) { if (code != 0) {
Die(errno, NULL); Die(errno, NULL);
return 1; return 1;
@ -4491,7 +4536,7 @@ RxStatPeerCmd(struct cmd_syndesc *as, void *arock)
blob.in_size = sizeof(afs_int32); blob.in_size = sizeof(afs_int32);
blob.out_size = 0; blob.out_size = 0;
code = pioctl(NULL, VIOC_RXSTAT_PEER, &blob, 1); code = pioctl_utf8(NULL, VIOC_RXSTAT_PEER, &blob, 1);
if (code != 0) { if (code != 0) {
Die(errno, NULL); Die(errno, NULL);
return 1; return 1;
@ -4571,7 +4616,7 @@ TestVolStatCmd(struct cmd_syndesc *as, void *arock)
blob.in_size = sizeof(test); blob.in_size = sizeof(test);
blob.out_size = 0; blob.out_size = 0;
code = pioctl(NULL, VIOC_VOLSTAT_TEST, &blob, 1); code = pioctl_utf8(NULL, VIOC_VOLSTAT_TEST, &blob, 1);
if (code != 0) { if (code != 0) {
Die(errno, NULL); Die(errno, NULL);
return 1; return 1;
@ -4584,10 +4629,55 @@ TestVolStatCmd(struct cmd_syndesc *as, void *arock)
#include "AFS_component_version_number.c" #include "AFS_component_version_number.c"
#endif #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; afs_int32 code;
struct cmd_syndesc *ts; struct cmd_syndesc *ts;
char ** argv;
#ifdef AFS_AIX32_ENV #ifdef AFS_AIX32_ENV
/* /*
@ -4609,6 +4699,8 @@ main(int argc, char **argv)
WSAStartup(0x0101, &WSAjunk); WSAStartup(0x0101, &WSAjunk);
#endif /* WIN32 */ #endif /* WIN32 */
argv = MakeUtf8Cmdline(argc, wargv);
/* try to find volume location information */ /* try to find volume location information */
osi_Init(); osi_Init();
@ -4885,11 +4977,17 @@ main(int argc, char **argv)
cmd_AddParm(ts, "-volume", CMD_SINGLE, CMD_OPTIONAL, "volume name or number"); 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"); 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); code = cmd_Dispatch(argc, argv);
if (rxInitDone) if (rxInitDone)
rx_Finalize(); rx_Finalize();
FreeUtf8CmdLine(argc, argv);
return code; return code;
} }

View File

@ -74,8 +74,7 @@ long fs_GetFullPath(char *pathp, char *outPathp, long outSize)
/* there's a drive letter there */ /* there's a drive letter there */
firstp = pathp+2; firstp = pathp+2;
pathHasDrive = 1; pathHasDrive = 1;
} } else {
else {
firstp = pathp; firstp = pathp;
pathHasDrive = 0; pathHasDrive = 0;
} }
@ -86,7 +85,7 @@ long fs_GetFullPath(char *pathp, char *outPathp, long outSize)
return 0; return 0;
} }
GetCurrentDirectory(sizeof(origPath), origPath); GetCurrentDirectoryA(sizeof(origPath), origPath);
doSwitch = 0; doSwitch = 0;
if (pathHasDrive && (*pathp & ~0x20) != (origPath[0] & ~0x20)) { if (pathHasDrive && (*pathp & ~0x20) != (origPath[0] & ~0x20)) {
@ -98,14 +97,14 @@ long fs_GetFullPath(char *pathp, char *outPathp, long outSize)
newPath[0] = *pathp; newPath[0] = *pathp;
newPath[1] = ':'; newPath[1] = ':';
newPath[2] = 0; newPath[2] = 0;
if (!SetCurrentDirectory(newPath)) { if (!SetCurrentDirectoryA(newPath)) {
code = GetLastError(); code = GetLastError();
return code; return code;
} }
} }
/* now get the absolute path to the current wdir in this drive */ /* 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 */ strcpy(outPathp, tpath+2); /* skip drive letter */
/* if there is a non-null name after the drive, append it */ /* if there is a non-null name after the drive, append it */
if (*firstp != 0) { if (*firstp != 0) {
@ -115,7 +114,7 @@ long fs_GetFullPath(char *pathp, char *outPathp, long outSize)
/* finally, if necessary, switch back to our home drive letter */ /* finally, if necessary, switch back to our home drive letter */
if (doSwitch) { if (doSwitch) {
SetCurrentDirectory(origPath); SetCurrentDirectoryA(origPath);
} }
return 0; return 0;
@ -197,9 +196,9 @@ void fs_utils_InitMountRoot()
char *pmount=mountRoot; char *pmount=mountRoot;
DWORD len=sizeof(mountRoot)-1; DWORD len=sizeof(mountRoot)-1;
printf("int mountroot \n"); 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) (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) || (len==sizeof(mountRoot)-1)
) )
strcpy(mountRoot, "\\afs"); strcpy(mountRoot, "\\afs");

View File

@ -31,6 +31,9 @@
#include "smb.h" #include "smb.h"
#include "lanahelper.h" #include "lanahelper.h"
#define STRSAFE_NO_DEPRECATE
#include <strsafe.h>
/* These characters are illegal in Windows filenames */ /* These characters are illegal in Windows filenames */
static char *illegalChars = "\\/:*?\"<>|"; static char *illegalChars = "\\/:*?\"<>|";
@ -133,6 +136,9 @@ smb_dirSearch_t *smb_lastDirSearchp;
/* hide dot files? */ /* hide dot files? */
int smb_hideDotFiles; int smb_hideDotFiles;
/* Negotiate Unicode support? */
LONG smb_UseUnicode;
/* global state about V3 protocols */ /* global state about V3 protocols */
int smb_useV3; /* try to negotiate V3 */ int smb_useV3; /* try to negotiate V3 */
@ -2065,7 +2071,7 @@ static smb_packet_t *GetPacket(void)
smb_packetFreeListp = tbp->nextp; smb_packetFreeListp = tbp->nextp;
lock_ReleaseWrite(&smb_globalLock); lock_ReleaseWrite(&smb_globalLock);
if (!tbp) { if (!tbp) {
tbp = calloc(65540,1); tbp = calloc(sizeof(*tbp),1);
tbp->magic = SMB_PACKETMAGIC; tbp->magic = SMB_PACKETMAGIC;
tbp->ncbp = NULL; tbp->ncbp = NULL;
tbp->vcp = NULL; tbp->vcp = NULL;
@ -2078,7 +2084,7 @@ static smb_packet_t *GetPacket(void)
tbp->ncb_length = 0; tbp->ncb_length = 0;
tbp->flags = 0; tbp->flags = 0;
tbp->spacep = NULL; tbp->spacep = NULL;
tbp->stringsp = NULL;
} }
osi_assertx(tbp->magic == SMB_PACKETMAGIC, "invalid smb_packet_t magic"); osi_assertx(tbp->magic == SMB_PACKETMAGIC, "invalid smb_packet_t magic");
@ -2091,6 +2097,7 @@ smb_packet_t *smb_CopyPacket(smb_packet_t *pkt)
tbp = GetPacket(); tbp = GetPacket();
memcpy(tbp, pkt, sizeof(smb_packet_t)); memcpy(tbp, pkt, sizeof(smb_packet_t));
tbp->wctp = tbp->data + (unsigned int)(pkt->wctp - pkt->data); tbp->wctp = tbp->data + (unsigned int)(pkt->wctp - pkt->data);
tbp->stringsp = NULL;
if (tbp->vcp) if (tbp->vcp)
smb_HoldVC(tbp->vcp); smb_HoldVC(tbp->vcp);
return tbp; return tbp;
@ -2118,6 +2125,18 @@ static NCB *GetNCB(void)
return ncbp; 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) void smb_FreePacket(smb_packet_t *tbp)
{ {
smb_vc_t * vcp = NULL; smb_vc_t * vcp = NULL;
@ -2138,6 +2157,7 @@ void smb_FreePacket(smb_packet_t *tbp)
tbp->oddByte = 0; tbp->oddByte = 0;
tbp->ncb_length = 0; tbp->ncb_length = 0;
tbp->flags = 0; tbp->flags = 0;
FreeSMBStrings(tbp);
lock_ReleaseWrite(&smb_globalLock); lock_ReleaseWrite(&smb_globalLock);
if (vcp) if (vcp)
@ -2345,6 +2365,8 @@ void smb_SetSMBParmByte(smb_packet_t *smbp, int slot, unsigned int parmValue)
*parmDatap++ = parmValue & 0xff; *parmDatap++ = parmValue & 0xff;
} }
void smb_StripLastComponent(char *outPathp, char **lastComponentp, char *inPathp) void smb_StripLastComponent(char *outPathp, char **lastComponentp, char *inPathp)
{ {
char *lastSlashp; char *lastSlashp;
@ -2365,14 +2387,286 @@ void smb_StripLastComponent(char *outPathp, char **lastComponentp, char *inPathp
} }
} }
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) if (*inp++ != 0x4)
return NULL; return NULL;
if (chainpp) {
*chainpp = inp + strlen(inp) + 1; /* skip over null-terminated string */ #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;
}
if ((flags & SMB_STRF_ANSIPATH) && smb_StoreAnsiFilenames)
OemToChar(inp, inp);
return 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) unsigned char *smb_ParseVblBlock(unsigned char *inp, char **chainpp, int *lengthp)
@ -2394,6 +2688,23 @@ unsigned char *smb_ParseVblBlock(unsigned char *inp, char **chainpp, int *length
return inp; 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 */ /* format a packet as a response */
void smb_FormatResponsePacket(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *op) void smb_FormatResponsePacket(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *op)
{ {
@ -2427,6 +2738,10 @@ void smb_FormatResponsePacket(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *op
outp->reb |= SMB_FLAGS_CANONICAL_PATHNAMES; outp->reb |= SMB_FLAGS_CANONICAL_PATHNAMES;
#endif #endif
outp->flg2 = SMB_FLAGS2_KNOWS_LONG_NAMES; 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 */ /* copy fields in generic packet area */
op->wctp = &outp->wct; op->wctp = &outp->wct;
@ -2831,6 +3146,7 @@ long smb_SendCoreBadOp(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
return CM_ERROR_BADOP; return CM_ERROR_BADOP;
} }
/* SMB_COM_ECHO */
long smb_ReceiveCoreEcho(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) long smb_ReceiveCoreEcho(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{ {
unsigned short EchoCount, i; unsigned short EchoCount, i;
@ -2851,6 +3167,7 @@ long smb_ReceiveCoreEcho(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
return 0; return 0;
} }
/* SMB_COM_READ_RAW */
long smb_ReceiveCoreReadRaw(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) long smb_ReceiveCoreReadRaw(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{ {
osi_hyper_t offset; osi_hyper_t offset;
@ -3012,6 +3329,7 @@ long smb_ReceiveCoreUnlockRecord(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t
return 0; return 0;
} }
/* SMB_COM_NEGOTIATE */
long smb_ReceiveNegotiate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) long smb_ReceiveNegotiate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{ {
char *namep; char *namep;
@ -3131,7 +3449,8 @@ long smb_ReceiveNegotiate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
* and NT Find * * and NT Find *
* and NT SMB's * * and NT SMB's *
* and raw mode * and raw mode
* and DFS */ * and DFS
* and Unicode */
caps = NTNEGOTIATE_CAPABILITY_NTSTATUS | caps = NTNEGOTIATE_CAPABILITY_NTSTATUS |
#ifdef DFS_SUPPORT #ifdef DFS_SUPPORT
NTNEGOTIATE_CAPABILITY_DFS | NTNEGOTIATE_CAPABILITY_DFS |
@ -3146,6 +3465,12 @@ long smb_ReceiveNegotiate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
if ( smb_authType == SMB_AUTH_EXTENDED ) if ( smb_authType == SMB_AUTH_EXTENDED )
caps |= NTNEGOTIATE_CAPABILITY_EXTENDED_SECURITY; caps |= NTNEGOTIATE_CAPABILITY_EXTENDED_SECURITY;
#ifdef SMB_UNICODE
if ( smb_UseUnicode ) {
caps |= NTNEGOTIATE_CAPABILITY_UNICODE;
}
#endif
smb_SetSMBParmLong(outp, 9, caps); smb_SetSMBParmLong(outp, 9, caps);
time(&unixTime); time(&unixTime);
smb_SearchTimeFromUnixTime(&dosTime, unixTime); smb_SearchTimeFromUnixTime(&dosTime, unixTime);
@ -3521,6 +3846,7 @@ long smb_ReceiveCoreGetDiskAttributes(smb_vc_t *vcp, smb_packet_t *inp, smb_pack
return 0; return 0;
} }
/* SMB_COM_TREE_CONNECT */
long smb_ReceiveCoreTreeConnect(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *rsp) long smb_ReceiveCoreTreeConnect(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *rsp)
{ {
smb_tid_t *tidp; smb_tid_t *tidp;
@ -3531,17 +3857,13 @@ long smb_ReceiveCoreTreeConnect(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *
int shareFound; int shareFound;
char *tp; char *tp;
char *pathp; char *pathp;
char *passwordp;
cm_user_t *userp; cm_user_t *userp;
osi_Log0(smb_logp, "SMB receive tree connect"); osi_Log0(smb_logp, "SMB receive tree connect");
/* parse input parameters */ /* parse input parameters */
tp = smb_GetSMBData(inp, NULL); tp = smb_GetSMBData(inp, NULL);
pathp = smb_ParseASCIIBlock(tp, &tp); pathp = smb_ParseASCIIBlock(inp, tp, &tp, SMB_STRF_ANSIPATH);
if (smb_StoreAnsiFilenames)
OemToChar(pathp,pathp);
passwordp = smb_ParseASCIIBlock(tp, &tp);
tp = strrchr(pathp, '\\'); tp = strrchr(pathp, '\\');
if (!tp) if (!tp)
return CM_ERROR_BADSMB; return CM_ERROR_BADSMB;
@ -3575,23 +3897,6 @@ long smb_ReceiveCoreTreeConnect(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *
return 0; 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. /* set maskp to the mask part of the incoming path.
* Mask is 11 bytes long (8.3 with the dot elided). * Mask is 11 bytes long (8.3 with the dot elided).
* Returns true if succeeds with a valid name, otherwise it does * Returns true if succeeds with a valid name, otherwise it does
@ -3709,6 +4014,10 @@ char *smb_FindMask(char *pathp)
return pathp; /* no slash, return the entire path */ 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) long smb_ReceiveCoreSearchVolume(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{ {
unsigned char *pathp; unsigned char *pathp;
@ -3722,10 +4031,9 @@ long smb_ReceiveCoreSearchVolume(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t
/* pull pathname and stat block out of request */ /* pull pathname and stat block out of request */
tp = smb_GetSMBData(inp, NULL); 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"); osi_assertx(pathp != NULL, "null path");
if (smb_StoreAnsiFilenames)
OemToChar(pathp,pathp);
statBlockp = smb_ParseVblBlock(tp, (char **) &tp, &statLen); statBlockp = smb_ParseVblBlock(tp, (char **) &tp, &statLen);
osi_assertx(statBlockp != NULL, "null statBlock"); osi_assertx(statBlockp != NULL, "null statBlock");
if (statLen == 0) { if (statLen == 0) {
@ -3768,6 +4076,9 @@ long smb_ReceiveCoreSearchVolume(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t
*tp++ = 0; *tp++ = 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 */ /* finally, null-terminated 8.3 pathname, which we set to AFS */
memset(tp, ' ', 13); memset(tp, ' ', 13);
strcpy(tp, "AFS"); strcpy(tp, "AFS");
@ -3863,6 +4174,7 @@ smb_ApplyDirListPatches(smb_dirListPatch_t **dirPatchespp,
return code; return code;
} }
/* SMB_COM_SEARCH */
long smb_ReceiveCoreSearchDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) long smb_ReceiveCoreSearchDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{ {
int attribute; int attribute;
@ -3918,9 +4230,8 @@ long smb_ReceiveCoreSearchDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *ou
caseFold = CM_FLAG_CASEFOLD; caseFold = CM_FLAG_CASEFOLD;
tp = smb_GetSMBData(inp, NULL); tp = smb_GetSMBData(inp, NULL);
pathp = smb_ParseASCIIBlock(tp, &tp); pathp = smb_ParseASCIIBlock(inp, tp, &tp,
if (smb_StoreAnsiFilenames) SMB_STRF_ANSIPATH|SMB_STRF_FORCEASCII);
OemToChar(pathp,pathp);
inCookiep = smb_ParseVblBlock(tp, &tp, &dataLength); inCookiep = smb_ParseVblBlock(tp, &tp, &dataLength);
/* bail out if request looks bad */ /* bail out if request looks bad */
@ -4337,6 +4648,8 @@ long smb_ReceiveCoreSearchDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *ou
strncpy(op, actualName, 13); strncpy(op, actualName, 13);
if (smb_StoreAnsiFilenames) if (smb_StoreAnsiFilenames)
CharToOem(op, op); CharToOem(op, op);
/* This is a UCHAR field, which is ASCII even if Unicode
is negotiated. */
/* Uppercase if requested by client */ /* Uppercase if requested by client */
if (!KNOWS_LONG_NAMES(inp)) if (!KNOWS_LONG_NAMES(inp))
@ -4404,8 +4717,11 @@ long smb_ReceiveCoreSearchDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *ou
return code; return code;
} }
/* verify that this is a valid path to a directory. I don't know why they /* verify that this is a valid path to a directory. I don't know why they
* don't use the get file attributes call. * 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) long smb_ReceiveCoreCheckPath(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{ {
@ -4422,11 +4738,9 @@ long smb_ReceiveCoreCheckPath(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *ou
cm_InitReq(&req); cm_InitReq(&req);
pathp = smb_GetSMBData(inp, NULL); pathp = smb_GetSMBData(inp, NULL);
pathp = smb_ParseASCIIBlock(pathp, NULL); pathp = smb_ParseASCIIBlock(inp, pathp, NULL, SMB_STRF_ANSIPATH);
if (!pathp) if (!pathp)
return CM_ERROR_BADFD; return CM_ERROR_BADFD;
if (smb_StoreAnsiFilenames)
OemToChar(pathp,pathp);
osi_Log1(smb_logp, "SMB receive check path %s", osi_Log1(smb_logp, "SMB receive check path %s",
osi_LogSaveString(smb_logp, pathp)); osi_LogSaveString(smb_logp, pathp));
@ -4489,6 +4803,7 @@ long smb_ReceiveCoreCheckPath(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *ou
return code; return code;
} }
/* SMB_COM_SET_INFORMATION */
long smb_ReceiveCoreSetFileAttributes(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) long smb_ReceiveCoreSetFileAttributes(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{ {
char *pathp; char *pathp;
@ -4510,11 +4825,9 @@ long smb_ReceiveCoreSetFileAttributes(smb_vc_t *vcp, smb_packet_t *inp, smb_pack
dosTime = smb_GetSMBParm(inp, 1) | (smb_GetSMBParm(inp, 2) << 16); dosTime = smb_GetSMBParm(inp, 1) | (smb_GetSMBParm(inp, 2) << 16);
pathp = smb_GetSMBData(inp, NULL); pathp = smb_GetSMBData(inp, NULL);
pathp = smb_ParseASCIIBlock(pathp, NULL); pathp = smb_ParseASCIIBlock(inp, pathp, NULL, SMB_STRF_ANSIPATH);
if (!pathp) if (!pathp)
return CM_ERROR_BADSMB; return CM_ERROR_BADSMB;
if (smb_StoreAnsiFilenames)
OemToChar(pathp,pathp);
osi_Log2(smb_logp, "SMB receive setfile attributes time %d, attr 0x%x", osi_Log2(smb_logp, "SMB receive setfile attributes time %d, attr 0x%x",
dosTime, attribute); dosTime, attribute);
@ -4604,6 +4917,7 @@ long smb_ReceiveCoreSetFileAttributes(smb_vc_t *vcp, smb_packet_t *inp, smb_pack
return code; return code;
} }
long smb_ReceiveCoreGetFileAttributes(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) long smb_ReceiveCoreGetFileAttributes(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{ {
char *pathp; char *pathp;
@ -4622,15 +4936,12 @@ long smb_ReceiveCoreGetFileAttributes(smb_vc_t *vcp, smb_packet_t *inp, smb_pack
cm_InitReq(&req); cm_InitReq(&req);
pathp = smb_GetSMBData(inp, NULL); pathp = smb_GetSMBData(inp, NULL);
pathp = smb_ParseASCIIBlock(pathp, NULL); pathp = smb_ParseASCIIBlock(inp, pathp, NULL, SMB_STRF_ANSIPATH);
if (!pathp) if (!pathp)
return CM_ERROR_BADSMB; return CM_ERROR_BADSMB;
if (*pathp == 0) /* null path */ if (*pathp == 0) /* null path */
pathp = "\\"; pathp = "\\";
else
if (smb_StoreAnsiFilenames)
OemToChar(pathp,pathp);
osi_Log1(smb_logp, "SMB receive getfile attributes path %s", osi_Log1(smb_logp, "SMB receive getfile attributes path %s",
osi_LogSaveString(smb_logp, pathp)); osi_LogSaveString(smb_logp, pathp));
@ -4770,6 +5081,7 @@ long smb_ReceiveCoreGetFileAttributes(smb_vc_t *vcp, smb_packet_t *inp, smb_pack
return 0; return 0;
} }
/* SMB_COM_TREE_DISCONNECT */
long smb_ReceiveCoreTreeDisconnect(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) long smb_ReceiveCoreTreeDisconnect(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{ {
smb_tid_t *tidp; smb_tid_t *tidp;
@ -4788,6 +5100,7 @@ long smb_ReceiveCoreTreeDisconnect(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_
return 0; return 0;
} }
/* SMB_COM_0PEN */
long smb_ReceiveCoreOpen(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) long smb_ReceiveCoreOpen(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{ {
smb_fid_t *fidp; smb_fid_t *fidp;
@ -4807,9 +5120,7 @@ long smb_ReceiveCoreOpen(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
cm_InitReq(&req); cm_InitReq(&req);
pathp = smb_GetSMBData(inp, NULL); pathp = smb_GetSMBData(inp, NULL);
pathp = smb_ParseASCIIBlock(pathp, NULL); pathp = smb_ParseASCIIBlock(inp, pathp, NULL, SMB_STRF_ANSIPATH);
if (smb_StoreAnsiFilenames)
OemToChar(pathp,pathp);
osi_Log1(smb_logp, "SMB receive open file [%s]", osi_LogSaveString(smb_logp, pathp)); osi_Log1(smb_logp, "SMB receive open file [%s]", osi_LogSaveString(smb_logp, pathp));
@ -4994,6 +5305,7 @@ int smb_UnlinkProc(cm_scache_t *dscp, cm_dirEntry_t *dep, void *vrockp, osi_hype
return code; return code;
} }
/* SMB_COM_DELETE */
long smb_ReceiveCoreUnlink(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) long smb_ReceiveCoreUnlink(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{ {
int attribute; int attribute;
@ -5015,9 +5327,7 @@ long smb_ReceiveCoreUnlink(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
attribute = smb_GetSMBParm(inp, 0); attribute = smb_GetSMBParm(inp, 0);
tp = smb_GetSMBData(inp, NULL); tp = smb_GetSMBData(inp, NULL);
pathp = smb_ParseASCIIBlock(tp, &tp); pathp = smb_ParseASCIIBlock(inp, tp, &tp, SMB_STRF_ANSIPATH);
if (smb_StoreAnsiFilenames)
OemToChar(pathp,pathp);
osi_Log1(smb_logp, "SMB receive unlink %s", osi_Log1(smb_logp, "SMB receive unlink %s",
osi_LogSaveString(smb_logp, pathp)); osi_LogSaveString(smb_logp, pathp));
@ -5521,6 +5831,7 @@ smb_Link(smb_vc_t *vcp, smb_packet_t *inp, char * oldPathp, char * newPathp)
return code; return code;
} }
/* SMB_COM_RENAME */
long long
smb_ReceiveCoreRename(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) smb_ReceiveCoreRename(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{ {
@ -5530,12 +5841,8 @@ smb_ReceiveCoreRename(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
long code; long code;
tp = smb_GetSMBData(inp, NULL); tp = smb_GetSMBData(inp, NULL);
oldPathp = smb_ParseASCIIBlock(tp, &tp); oldPathp = smb_ParseASCIIBlock(inp, tp, &tp, SMB_STRF_ANSIPATH);
if (smb_StoreAnsiFilenames) newPathp = smb_ParseASCIIBlock(inp, tp, &tp, SMB_STRF_ANSIPATH);
OemToChar(oldPathp,oldPathp);
newPathp = smb_ParseASCIIBlock(tp, &tp);
if (smb_StoreAnsiFilenames)
OemToChar(newPathp,newPathp);
osi_Log2(smb_logp, "smb rename [%s] to [%s]", osi_Log2(smb_logp, "smb rename [%s] to [%s]",
osi_LogSaveString(smb_logp, oldPathp), osi_LogSaveString(smb_logp, oldPathp),
@ -5590,6 +5897,7 @@ int smb_RmdirProc(cm_scache_t *dscp, cm_dirEntry_t *dep, void *vrockp, osi_hyper
return 0; return 0;
} }
long smb_ReceiveCoreRemoveDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) long smb_ReceiveCoreRemoveDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{ {
long code = 0; long code = 0;
@ -5608,9 +5916,7 @@ long smb_ReceiveCoreRemoveDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *ou
cm_InitReq(&req); cm_InitReq(&req);
tp = smb_GetSMBData(inp, NULL); tp = smb_GetSMBData(inp, NULL);
pathp = smb_ParseASCIIBlock(tp, &tp); pathp = smb_ParseASCIIBlock(inp, tp, &tp, SMB_STRF_ANSIPATH);
if (smb_StoreAnsiFilenames)
OemToChar(pathp,pathp);
spacep = inp->spacep; spacep = inp->spacep;
smb_StripLastComponent(spacep->data, &lastNamep, pathp); smb_StripLastComponent(spacep->data, &lastNamep, pathp);
@ -5697,6 +6003,7 @@ long smb_ReceiveCoreRemoveDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *ou
return code; return code;
} }
/* SMB_COM_FLUSH */
long smb_ReceiveCoreFlush(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) long smb_ReceiveCoreFlush(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{ {
unsigned short fid; unsigned short fid;
@ -6003,6 +6310,7 @@ long smb_CloseFID(smb_vc_t *vcp, smb_fid_t *fidp, cm_user_t *userp,
return code; return code;
} }
/* SMB_COM_CLOSE */
long smb_ReceiveCoreClose(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) long smb_ReceiveCoreClose(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{ {
unsigned short fid; unsigned short fid;
@ -6465,6 +6773,7 @@ long smb_WriteData(smb_fid_t *fidp, osi_hyper_t *offsetp, afs_uint32 count, char
return code; return code;
} }
/* SMB_COM_WRITE */
long smb_ReceiveCoreWrite(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) long smb_ReceiveCoreWrite(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{ {
unsigned short fd; unsigned short fd;
@ -6669,6 +6978,7 @@ long smb_ReceiveCoreWriteRawDummy(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t
return 0; 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) long smb_ReceiveCoreWriteRaw(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp, raw_write_cont_t *rwcp)
{ {
osi_hyper_t offset; osi_hyper_t offset;
@ -6847,6 +7157,7 @@ long smb_ReceiveCoreWriteRaw(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out
return 0; return 0;
} }
/* SMB_COM_READ */
long smb_ReceiveCoreRead(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) long smb_ReceiveCoreRead(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{ {
osi_hyper_t offset; osi_hyper_t offset;
@ -6944,6 +7255,7 @@ long smb_ReceiveCoreRead(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
return code; return code;
} }
/* SMB_COM_CREATE_DIRECTORY */
long smb_ReceiveCoreMakeDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) long smb_ReceiveCoreMakeDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{ {
char *pathp; char *pathp;
@ -6968,9 +7280,7 @@ long smb_ReceiveCoreMakeDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp
initialModeBits = 0777; initialModeBits = 0777;
tp = smb_GetSMBData(inp, NULL); tp = smb_GetSMBData(inp, NULL);
pathp = smb_ParseASCIIBlock(tp, &tp); pathp = smb_ParseASCIIBlock(inp, tp, &tp, SMB_STRF_ANSIPATH);
if (smb_StoreAnsiFilenames)
OemToChar(pathp,pathp);
if (strcmp(pathp, "\\") == 0) if (strcmp(pathp, "\\") == 0)
return CM_ERROR_EXISTS; return CM_ERROR_EXISTS;
@ -7063,6 +7373,7 @@ BOOL smb_IsLegalFilename(char *filename)
return TRUE; 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) long smb_ReceiveCoreCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{ {
char *pathp; char *pathp;
@ -7098,9 +7409,7 @@ long smb_ReceiveCoreCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
initialModeBits &= ~0222; initialModeBits &= ~0222;
tp = smb_GetSMBData(inp, NULL); tp = smb_GetSMBData(inp, NULL);
pathp = smb_ParseASCIIBlock(tp, &tp); pathp = smb_ParseASCIIBlock(inp, tp, &tp, SMB_STRF_ANSIPATH);
if (smb_StoreAnsiFilenames)
OemToChar(pathp,pathp);
spacep = inp->spacep; spacep = inp->spacep;
smb_StripLastComponent(spacep->data, &lastNamep, pathp); smb_StripLastComponent(spacep->data, &lastNamep, pathp);
@ -7262,6 +7571,7 @@ long smb_ReceiveCoreCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
return 0; return 0;
} }
/* SMB_COM_SEEK */
long smb_ReceiveCoreSeek(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) long smb_ReceiveCoreSeek(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{ {
long code = 0; long code = 0;
@ -7436,9 +7746,11 @@ void smb_DispatchPacket(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp,
/* Raw Write */ /* Raw Write */
code = smb_ReceiveCoreWriteRaw (vcp, inp, outp, rwcp); code = smb_ReceiveCoreWriteRaw (vcp, inp, outp, rwcp);
else { 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); 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 #ifdef LOG_PACKET
if ( code == CM_ERROR_BADSMB || if ( code == CM_ERROR_BADSMB ||
code == CM_ERROR_BADOP ) code == CM_ERROR_BADOP )
@ -7455,8 +7767,9 @@ void smb_DispatchPacket(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp,
osi_Log3(smb_logp, "Request %s straddled session startup, " osi_Log3(smb_logp, "Request %s straddled session startup, "
"took %d ms, ncb length %d", opName, newTime - oldTime, ncbp->ncb_length); "took %d ms, ncb length %d", opName, newTime - oldTime, ncbp->ncb_length);
} }
}
else { FreeSMBStrings(inp);
} else {
/* bad opcode, fail the request, after displaying it */ /* bad opcode, fail the request, after displaying it */
osi_Log1(smb_logp, "Received bad SMB req 0x%X", inp->inCom); osi_Log1(smb_logp, "Received bad SMB req 0x%X", inp->inCom);
#ifdef LOG_PACKET #ifdef LOG_PACKET
@ -7976,8 +8289,10 @@ void smb_Server(VOID *parmp)
smbp = (smb_t *)bufp->data; smbp = (smb_t *)bufp->data;
outbufp->flags = 0; outbufp->flags = 0;
#ifndef NOTRACE
__try __try
{ {
#endif
if (smbp->com == 0x1d) { if (smbp->com == 0x1d) {
/* Special handling for Write Raw */ /* Special handling for Write Raw */
raw_write_cont_t rwc; raw_write_cont_t rwc;
@ -8015,9 +8330,11 @@ void smb_Server(VOID *parmp)
/* TODO: what else needs to be serialized? */ /* TODO: what else needs to be serialized? */
smb_DispatchPacket(vcp, bufp, outbufp, ncbp, NULL); smb_DispatchPacket(vcp, bufp, outbufp, ncbp, NULL);
} }
#ifndef NOTRACE
} }
__except( smb_ServerExceptionFilter() ) { __except( smb_ServerExceptionFilter() ) {
} }
#endif
smb_concurrentCalls--; smb_concurrentCalls--;
@ -8316,6 +8633,7 @@ void smb_Listener(void *parmp)
smbp->errHigh = (unsigned char) ((errCode >> 8) & 0xff); smbp->errHigh = (unsigned char) ((errCode >> 8) & 0xff);
smbp->rcls = errClass; smbp->rcls = errClass;
} }
smb_SendPacket(vcp, outp); smb_SendPacket(vcp, outp);
smb_FreePacket(outp); smb_FreePacket(outp);
@ -9290,6 +9608,7 @@ char *smb_GetSharename()
void smb_LogPacket(smb_packet_t *packet) void smb_LogPacket(smb_packet_t *packet)
{ {
BYTE *vp, *cp; BYTE *vp, *cp;
smb_t * smbp;
unsigned length, paramlen, datalen, i, j; unsigned length, paramlen, datalen, i, j;
char buf[81]; char buf[81];
char hex[]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'}; char hex[]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
@ -9298,11 +9617,12 @@ void smb_LogPacket(smb_packet_t *packet)
osi_Log0(smb_logp, "*** SMB packet dump ***"); osi_Log0(smb_logp, "*** SMB packet dump ***");
smbp = (smb_t *) packet->data;
vp = (BYTE *) packet->data; vp = (BYTE *) packet->data;
datalen = *((WORD*)(vp + (paramlen = ((unsigned)*(vp+20)) << 1))); paramlen = smbp->wct * 2;
length = paramlen + 2 + datalen; datalen = *((WORD *) (smbp->vdata + paramlen));
length = sizeof(*smbp) + paramlen + 1 + datalen;
for (i=0;i < length; i+=16) for (i=0;i < length; i+=16)
{ {

View File

@ -64,6 +64,7 @@ typedef struct smb {
#define KNOWS_LONG_NAMES(inp) ((((smb_t *)inp)->flg2 & SMB_FLAGS2_KNOWS_LONG_NAMES)?1:0) #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_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 */ /* Information Levels */
#define SMB_INFO_STANDARD 1 #define SMB_INFO_STANDARD 1
@ -125,6 +126,8 @@ typedef struct smb {
#define SMB_PACKETSIZE 32768 /* was 8400 */ #define SMB_PACKETSIZE 32768 /* was 8400 */
/* raw mode is considered obsolete and cannot be used with message signing */ /* raw mode is considered obsolete and cannot be used with message signing */
#define SMB_MAXRAWSIZE 65536 #define SMB_MAXRAWSIZE 65536
/* max STRING characters per packet per request */
#define SMB_STRINGBUFSIZE 4096
/* Negotiate protocol constants */ /* Negotiate protocol constants */
/* Security */ /* Security */
@ -186,6 +189,7 @@ typedef struct smb_packet {
unsigned char oddByte; unsigned char oddByte;
unsigned short ncb_length; unsigned short ncb_length;
unsigned char flags; unsigned char flags;
cm_space_t *stringsp; /* decoded strings from this packet */
} smb_packet_t; } smb_packet_t;
/* smb_packet flags */ /* smb_packet flags */
@ -242,6 +246,7 @@ typedef struct smb_vc {
#define SMB_VCFLAG_SESSX_RCVD 0x40 /* we received at least one session setups on this vc */ #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_AUTH_IN_PROGRESS 0x80 /* a SMB NT extended authentication is in progress */
#define SMB_VCFLAG_CLEAN_IN_PROGRESS 0x100 #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 */ /* one per user session */
typedef struct smb_user { typedef struct smb_user {
@ -338,11 +343,13 @@ typedef struct smb_ioctl {
/* uid pointer */ /* uid pointer */
smb_user_t *uidp; smb_user_t *uidp;
} smb_ioctl_t; } smb_ioctl_t;
/* flags for smb_ioctl_t */ /* flags for smb_ioctl_t */
#define SMB_IOCTLFLAG_DATAIN 1 /* reading data from client to server */ #define SMB_IOCTLFLAG_DATAIN 1 /* reading data from client to server */
#define SMB_IOCTLFLAG_LOGON 2 /* got tokens from integrated logon */ #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 */ /* one per file ID; these are really file descriptors */
typedef struct smb_fid { typedef struct smb_fid {
@ -622,7 +629,30 @@ extern void smb_SetSMBParmByte(smb_packet_t *smbp, int slot, unsigned int parmVa
extern void smb_StripLastComponent(char *outPathp, char **lastComponentp, extern void smb_StripLastComponent(char *outPathp, char **lastComponentp,
char *inPathp); 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, extern unsigned char *smb_ParseVblBlock(unsigned char *inp, char **chainpp,
int *lengthp); int *lengthp);
@ -678,6 +708,7 @@ extern char smb_ServerLanManager[];
extern int smb_ServerLanManagerLength; extern int smb_ServerLanManagerLength;
extern GUID smb_ServerGUID; extern GUID smb_ServerGUID;
extern LSA_STRING smb_lsaLogonOrigin; extern LSA_STRING smb_lsaLogonOrigin;
extern LONG smb_UseUnicode;
/* used for getting a challenge for SMB auth */ /* used for getting a challenge for SMB auth */
typedef struct _MSV1_0_LM20_CHALLENGE_REQUEST { typedef struct _MSV1_0_LM20_CHALLENGE_REQUEST {
@ -709,8 +740,6 @@ extern int smb_ChainFID(int fid, smb_packet_t *inp);
extern unsigned char *smb_ParseDataBlock(unsigned char *inp, char **chainpp, int *lengthp); 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 unsigned char *smb_ParseVblBlock(unsigned char *inp, char **chainpp, int *lengthp);
extern int smb_SUser(cm_user_t *userp); extern int smb_SUser(cm_user_t *userp);

File diff suppressed because it is too large Load Diff

View File

@ -30,10 +30,12 @@ typedef struct smb_tran2Packet {
unsigned short res[6]; /* contains PidHigh */ unsigned short res[6]; /* contains PidHigh */
unsigned short *parmsp; /* parms */ unsigned short *parmsp; /* parms */
unsigned char *datap; /* data bytes */ unsigned char *datap; /* data bytes */
cm_space_t * stringsp; /* decoded strings */
} smb_tran2Packet_t; } smb_tran2Packet_t;
/* for flags field */ /* for flags field */
#define SMB_TRAN2PFLAG_ALLOC 1 #define SMB_TRAN2PFLAG_ALLOC 1
#define SMB_TRAN2PFLAG_USEUNICODE 2
typedef struct smb_tran2Dispatch { typedef struct smb_tran2Dispatch {
long (*procp)(smb_vc_t *, smb_tran2Packet_t *, smb_packet_t *); long (*procp)(smb_vc_t *, smb_tran2Packet_t *, smb_packet_t *);
@ -56,14 +58,14 @@ typedef struct smb_tran2QFSInfo {
struct { struct {
unsigned long vsn; /* volume serial number */ unsigned long vsn; /* volume serial number */
char vnCount; /* count of chars in label, incl null */ 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; } volumeInfo;
struct { struct {
FILETIME vct; /* volume creation time */ FILETIME vct; /* volume creation time */
unsigned long vsn; /* volume serial number */ unsigned long vsn; /* volume serial number */
unsigned long vnCount; /* length of volume label in bytes */ unsigned long vnCount; /* length of volume label in bytes */
char res[2]; /* reserved */ char res[2]; /* reserved */
char label[10]; /* volume label */ char /* STRING */ label[20]; /* volume label */
} FSvolumeInfo; } FSvolumeInfo;
struct { struct {
LARGE_INTEGER totalAllocUnits; /* on the disk */ LARGE_INTEGER totalAllocUnits; /* on the disk */
@ -79,7 +81,7 @@ typedef struct smb_tran2QFSInfo {
unsigned long attributes; unsigned long attributes;
unsigned long maxCompLength; /* max path component length */ unsigned long maxCompLength; /* max path component length */
unsigned long FSnameLength; /* length of file system name */ unsigned long FSnameLength; /* length of file system name */
unsigned char FSname[12]; unsigned char /* STRING */ FSname[24]; /* File system name */
} FSattributeInfo; } FSattributeInfo;
} u; } u;
} smb_tran2QFSInfo_t; } smb_tran2QFSInfo_t;
@ -137,7 +139,7 @@ typedef struct {
} QPfileEaInfo; } QPfileEaInfo;
struct { struct {
unsigned long fileNameLength; unsigned long fileNameLength;
unsigned char fileName[512]; unsigned char fileName[512]; /* STRING */
} QPfileNameInfo; } QPfileNameInfo;
struct { struct {
FILETIME creationTime; FILETIME creationTime;
@ -158,18 +160,18 @@ typedef struct {
unsigned long mode; unsigned long mode;
unsigned long alignmentRequirement; unsigned long alignmentRequirement;
unsigned long fileNameLength; unsigned long fileNameLength;
unsigned char fileName[512]; unsigned char fileName[512]; /* STRING */
} QPfileAllInfo; } QPfileAllInfo;
struct { struct {
unsigned long fileNameLength; unsigned long fileNameLength;
unsigned char fileName[512]; unsigned char fileName[512]; /* STRING */
} QPfileAltNameInfo; } QPfileAltNameInfo;
struct { struct {
unsigned long nextEntryOffset; unsigned long nextEntryOffset;
unsigned long streamNameLength; unsigned long streamNameLength;
LARGE_INTEGER streamSize; LARGE_INTEGER streamSize;
LARGE_INTEGER streamAllocationSize; LARGE_INTEGER streamAllocationSize;
unsigned char fileName[512]; unsigned char fileName[512]; /* STRING */
} QPfileStreamInfo; } QPfileStreamInfo;
struct { struct {
LARGE_INTEGER compressedFileSize; LARGE_INTEGER compressedFileSize;
@ -207,6 +209,79 @@ typedef struct {
} QFfileNameInfo; } QFfileNameInfo;
} u; } u;
} smb_tran2QFileInfo_t; } 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) #pragma pack(pop)
/* more than enough opcodes for today, anyway */ /* more than enough opcodes for today, anyway */

View File

@ -94,6 +94,7 @@ struct sbstruct {
#define VIOC_UUIDCTL 0x30 #define VIOC_UUIDCTL 0x30
#define VIOC_PATH_AVAILABILITY 0x31 #define VIOC_PATH_AVAILABILITY 0x31
#define VIOC_GETFILETYPE 0x32 #define VIOC_GETFILETYPE 0x32
#define VIOC_UNICODECTL 0x33
#define VIOC_VOLSTAT_TEST 0x3F #define VIOC_VOLSTAT_TEST 0x3F
/* Not to exceed SMB_IOCTL_MAXPROCS from smb_ioctl.h */ /* Not to exceed SMB_IOCTL_MAXPROCS from smb_ioctl.h */

View File

@ -82,6 +82,7 @@ void smb_InitIoctl(void)
smb_ioctlProcsp[VIOC_PATH_AVAILABILITY] = cm_IoctlPathAvailability; smb_ioctlProcsp[VIOC_PATH_AVAILABILITY] = cm_IoctlPathAvailability;
smb_ioctlProcsp[VIOC_GETFILETYPE] = cm_IoctlGetFileType; smb_ioctlProcsp[VIOC_GETFILETYPE] = cm_IoctlGetFileType;
smb_ioctlProcsp[VIOC_VOLSTAT_TEST] = cm_IoctlVolStatTest; smb_ioctlProcsp[VIOC_VOLSTAT_TEST] = cm_IoctlVolStatTest;
smb_ioctlProcsp[VIOC_UNICODECTL] = cm_IoctlUnicodeControl;
} }
/* called to make a fid structure into an IOCTL fid structure */ /* called to make a fid structure into an IOCTL fid structure */

View File

@ -68,7 +68,7 @@ static int InAFS(register char *apath)
blob.out_size = MAXSIZE; blob.out_size = MAXSIZE;
blob.out = space; 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 (code) {
if ((errno == EINVAL) || (errno == ENOENT)) if ((errno == EINVAL) || (errno == ENOENT))
return 0; return 0;
@ -86,7 +86,7 @@ IsFreelanceRoot(char *apath)
blob.out_size = MAXSIZE; blob.out_size = MAXSIZE;
blob.out = space; 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) if (code == 0)
return !stricmp("Freelance.Local.Root",space); return !stricmp("Freelance.Local.Root",space);
return 1; /* assume it is because it is more restrictive that way */ return 1; /* assume it is because it is more restrictive that way */
@ -399,7 +399,7 @@ static ListLinkCmd(register struct cmd_syndesc *as, void *arock)
blob.out = space; blob.out = space;
memset(space, 0, MAXSIZE); memset(space, 0, MAXSIZE);
code = pioctl(parent_dir, VIOC_LISTSYMLINK, &blob, 1); code = pioctl_utf8(parent_dir, VIOC_LISTSYMLINK, &blob, 1);
if (code == 0) if (code == 0)
printf("'%s' is a %ssymlink to '%s'\n", printf("'%s' is a %ssymlink to '%s'\n",
@ -460,6 +460,8 @@ static MakeLinkCmd(register struct cmd_syndesc *as, void *arock)
return 1; 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 /* create symlink with a special pioctl for Windows NT, since it doesn't
* have a symlink system call. * have a symlink system call.
*/ */
@ -467,7 +469,7 @@ static MakeLinkCmd(register struct cmd_syndesc *as, void *arock)
blob.in_size = 1 + (long)strlen(as->parms[1].items->data); blob.in_size = 1 + (long)strlen(as->parms[1].items->data);
blob.in = as->parms[1].items->data; blob.in = as->parms[1].items->data;
blob.out = NULL; blob.out = NULL;
code = pioctl(path, VIOC_SYMLINK, &blob, 0); code = pioctl_utf8(path, VIOC_SYMLINK, &blob, 0);
#else /* not WIN32 */ #else /* not WIN32 */
code = symlink(as->parms[1].items->data, path); code = symlink(as->parms[1].items->data, path);
#endif /* not WIN32 */ #endif /* not WIN32 */
@ -528,7 +530,7 @@ static RemoveLinkCmd(register struct cmd_syndesc *as, void *arock)
blob.in_size = (int)strlen(tp)+1; blob.in_size = (int)strlen(tp)+1;
blob.out = lsbuffer; blob.out = lsbuffer;
blob.out_size = sizeof(lsbuffer); blob.out_size = sizeof(lsbuffer);
code = pioctl(tbuffer, VIOC_LISTSYMLINK, &blob, 0); code = pioctl_utf8(tbuffer, VIOC_LISTSYMLINK, &blob, 0);
if (code) { if (code) {
if (errno == EINVAL) if (errno == EINVAL)
fprintf(stderr,"symlink: '%s' is not a symlink.\n", ti->data); fprintf(stderr,"symlink: '%s' is not a symlink.\n", ti->data);
@ -547,7 +549,7 @@ static RemoveLinkCmd(register struct cmd_syndesc *as, void *arock)
blob.out_size = 0; blob.out_size = 0;
blob.in = tp; blob.in = tp;
blob.in_size = (long)strlen(tp)+1; blob.in_size = (long)strlen(tp)+1;
code = pioctl(tbuffer, VIOC_DELSYMLINK, &blob, 0); code = pioctl_utf8(tbuffer, VIOC_DELSYMLINK, &blob, 0);
if (code) { if (code) {
Die(errno, ti->data); Die(errno, ti->data);
} }
@ -555,14 +557,58 @@ static RemoveLinkCmd(register struct cmd_syndesc *as, void *arock)
return code; 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 struct ViceIoctl gblob;
static int debug = 0; static int debug = 0;
main(argc, argv) int wmain(int argc, wchar_t **wargv)
int argc; {
char **argv; {
register afs_int32 code; register afs_int32 code;
register struct cmd_syndesc *ts; register struct cmd_syndesc *ts;
char ** argv;
#ifdef AFS_AIX32_ENV #ifdef AFS_AIX32_ENV
/* /*
@ -586,6 +632,7 @@ char **argv; {
/* try to find volume location information */ /* try to find volume location information */
argv = MakeUtf8Cmdline(argc, wargv);
osi_Init(); osi_Init();
@ -606,6 +653,8 @@ char **argv; {
if (rxInitDone) rx_Finalize(); if (rxInitDone) rx_Finalize();
#endif /* not WIN32 */ #endif /* not WIN32 */
FreeUtf8CmdLine(argc, argv);
return code; return code;
} }

View File

@ -24,6 +24,9 @@ extern "C" {
extern "C" { extern "C" {
#include "WINNT\afsreg.h" #include "WINNT\afsreg.h"
} }
#define STRSAFE_NO_DEPRECATE
#include <strsafe.h>
#ifdef _DEBUG #ifdef _DEBUG
#define new DEBUG_NEW #define new DEBUG_NEW
#undef THIS_FILE #undef THIS_FILE
@ -75,8 +78,10 @@ HINSTANCE g_hInstance;
BOOL CAfsShlExt::InitInstance() BOOL CAfsShlExt::InitInstance()
{ {
extern EXPORTED HINSTANCE TaLocale_LoadCorrespondingModuleByName (HINSTANCE hInstance, LPSTR pszFilename, WORD wSearchPriority = MODULE_PRIORITY_BOOSTED);
// Load our translated resources // 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 // Register all OLE server (factories) as running. This enables the
// OLE libraries to create objects from other applications. // OLE libraries to create objects from other applications.
@ -115,8 +120,12 @@ STDAPI DllCanUnloadNow(void)
int WideCharToLocal(LPTSTR pLocal, LPCWSTR pWide, DWORD dwChars) int WideCharToLocal(LPTSTR pLocal, LPCWSTR pWide, DWORD dwChars)
{ {
#ifdef UNICODE
StringCchCopy(pLocal, dwChars, pWide);
#else
*pLocal = 0; *pLocal = 0;
WideCharToMultiByte( CP_ACP, 0, pWide, -1, pLocal, dwChars, NULL, NULL); WideCharToMultiByte( CP_ACP, 0, pWide, -1, pLocal, dwChars, NULL, NULL);
#endif
return lstrlen(pLocal); return lstrlen(pLocal);
} }
@ -155,14 +164,12 @@ STDAPI DllRegisterServer(void)
StringFromIID(IID_IShellExt, &pwsz); StringFromIID(IID_IShellExt, &pwsz);
if(pwsz) if(pwsz)
{ {
#ifdef UNICODE
StringCbCopy(szCLSID, sizeof(szCLSID), pwsz);
#else
WideCharToMultiByte( CP_ACP, 0,pwsz, -1, szCLSID, sizeof(szCLSID), NULL, NULL); WideCharToMultiByte( CP_ACP, 0,pwsz, -1, szCLSID, sizeof(szCLSID), NULL, NULL);
LPMALLOC pMalloc; #endif
CoGetMalloc(1, &pMalloc); CoTaskMemFree(pwsz);
if(pMalloc)
{
(pMalloc->Free)(pwsz);
(pMalloc->Release)();
}
} else { } else {
return E_FAIL; return E_FAIL;
} }
@ -172,14 +179,15 @@ STDAPI DllRegisterServer(void)
@="Y:\\DEST\\root.client\\usr\\vice\\etc\\afs_shl_ext.dll" @="Y:\\DEST\\root.client\\usr\\vice\\etc\\afs_shl_ext.dll"
"ThreadingModel"="Apartment" "ThreadingModel"="Apartment"
*/ */
HMODULE hModule=GetModuleHandle("afs_shl_ext.dll"); HMODULE hModule=GetModuleHandle(TEXT("afs_shl_ext.dll"));
DWORD z=GetModuleFileName(hModule,szModule,sizeof(szModule)); DWORD z=GetModuleFileName(hModule,szModule,sizeof(szModule));
wsprintf(szSubKey, TEXT("CLSID\\%s\\InprocServer32"),szCLSID); wsprintf(szSubKey, TEXT("CLSID\\%s\\InprocServer32"),szCLSID);
if ((lResult=DoRegCLSID(HKEY_CLASSES_ROOT,szSubKey,szModule))!=NOERROR) if ((lResult=DoRegCLSID(HKEY_CLASSES_ROOT,szSubKey,szModule))!=NOERROR)
return lResult; return lResult;
wsprintf(szSubKey, TEXT("CLSID\\%s\\InprocServer32"),szCLSID); 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; return lResult;
/* /*
@ -206,7 +214,7 @@ STDAPI DllRegisterServer(void)
if(VER_PLATFORM_WIN32_NT == osvi.dwPlatformId) if(VER_PLATFORM_WIN32_NT == osvi.dwPlatformId)
{ {
wsprintf(szSubKey, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved")); 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; return lResult;
} }
wsprintf(szSubKey, TEXT("*\\shellex\\ContextMenuHandlers\\%s"),STR_EXT_TITLE); wsprintf(szSubKey, TEXT("*\\shellex\\ContextMenuHandlers\\%s"),STR_EXT_TITLE);
@ -276,7 +284,7 @@ STDAPI DllRegisterServer(void)
TCHAR szData[MAX_PATH]; TCHAR szData[MAX_PATH];
//Create the value string. //Create the value string.
lstrcpy(szData, STR_EXT_TITLE); lstrcpy(szData, _TEXT(STR_EXT_TITLE));
lResult = RegSetValueEx( hKey, lResult = RegSetValueEx( hKey,
szCLSID, szCLSID,
@ -325,14 +333,12 @@ STDAPI DllUnregisterServer(void)
StringFromIID(IID_IShellExt, &pwsz); StringFromIID(IID_IShellExt, &pwsz);
if(pwsz) if(pwsz)
{ {
#ifdef UNICODE
StringCbCopy(szCLSID, sizeof(szCLSID), pwsz);
#else
WideCharToMultiByte( CP_ACP, 0,pwsz, -1, szCLSID, sizeof(szCLSID), NULL, NULL); WideCharToMultiByte( CP_ACP, 0,pwsz, -1, szCLSID, sizeof(szCLSID), NULL, NULL);
LPMALLOC pMalloc; #endif
CoGetMalloc(1, &pMalloc); CoTaskMemFree(pwsz);
if(pMalloc)
{
(pMalloc->Free)(pwsz);
(pMalloc->Release)();
}
} else { } else {
return E_FAIL; return E_FAIL;
} }

View File

@ -8,6 +8,7 @@
*/ */
#include "stdafx.h" #include "stdafx.h"
#include <shlwapi.h>
#include <winsock2.h> #include <winsock2.h>
#include <ws2tcpip.h> #include <ws2tcpip.h>
@ -72,7 +73,7 @@ void CCopyAclDlg::OnOK()
m_bClear = m_Clear.GetCheck() == 1; m_bClear = m_Clear.GetCheck() == 1;
m_ToDir.GetWindowText(m_strToDir); 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); ShowMessageBox(IDS_DIR_DOES_NOT_EXIST_ERROR, MB_ICONEXCLAMATION, IDS_DIR_DOES_NOT_EXIST_ERROR, m_strToDir);
return; return;
} }
@ -100,7 +101,7 @@ void CCopyAclDlg::OnChangeToDir()
void CCopyAclDlg::OnBrowse() 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) if (dlg.DoModal() == IDCANCEL)
return; return;

File diff suppressed because it is too large Load Diff

View File

@ -18,9 +18,8 @@ void WSCellCmd();
void WhichCell(CStringArray& files); void WhichCell(CStringArray& files);
BOOL CheckVolumes(); BOOL CheckVolumes();
void SetCacheSize(LONG nNewCacheSize); void SetCacheSize(LONG nNewCacheSize);
void RemoveMountCmd(const CStringArray& files);
void WhereIs(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); void CleanACL(CStringArray& names);
BOOL GetRights(const CString& strDir, CStringArray& strNormal, CStringArray& strNegative); BOOL GetRights(const CString& strDir, CStringArray& strNormal, CStringArray& strNegative);
BOOL SaveACL(const CString& strCellName, const CString& strDir, const CStringArray& normal, const CStringArray& negative); BOOL SaveACL(const CString& strCellName, const CString& strDir, const CStringArray& normal, const CStringArray& negative);
@ -28,20 +27,16 @@ BOOL CopyACL(const CString& strToDir, const CStringArray& normal, const CStringA
BOOL ListMount(CStringArray& files); BOOL ListMount(CStringArray& files);
BOOL MakeMount(const CString& strDir, const CString& strVolName, const CString& strCellName, BOOL bRW); BOOL MakeMount(const CString& strDir, const CString& strVolName, const CString& strCellName, BOOL bRW);
BOOL RemoveMount(CStringArray& files); BOOL RemoveMount(CStringArray& files);
BOOL RemoveSymlink(const char *); BOOL RemoveSymlink(const CString& symlink);
BOOL GetVolumeInfo(CString strFile, CVolInfo& volInfo); BOOL GetVolumeInfo(CString strFile, CVolInfo& volInfo);
BOOL SetVolInfo(CVolInfo& volInfo); BOOL SetVolInfo(CVolInfo& volInfo);
enum WHICH_CELLS { LOCAL_CELL = 0, SPECIFIC_CELL = 1, ALL_CELLS = 2 }; enum WHICH_CELLS { LOCAL_CELL = 0, SPECIFIC_CELL = 1, ALL_CELLS = 2 };
BOOL CheckServers(const CString& strCellName, WHICH_CELLS nCellsToCheck, BOOL bFast); BOOL CheckServers(const CString& strCellName, WHICH_CELLS nCellsToCheck, BOOL bFast);
BOOL GetTokenInfo(CStringArray& tokenInfo); BOOL GetTokenInfo(CStringArray& tokenInfo);
BOOL IsPathInAfs(const CHAR *strPath); BOOL IsPathInAfs(const CString& strPath);
int GetCellName(char *baseNamep, struct afsconf_cell *infop); BOOL IsSymlink(const CString& name);
long fs_StripDriveLetter(const char *inPathp, char *outPathp, long outSize); BOOL IsMountPoint(const CString& name);
long fs_ExtractDriveLetter(const char *inPathp, char *outPathp); UINT MakeSymbolicLink(const CString&,const CString&);
BOOL IsSymlink(const char * true_name); void ListSymbolicLinkPath(CString&,CString&,UINT nlenPath);
BOOL IsMountPoint(const char * name);
UINT MakeSymbolicLink(const char *,const char *);
void ListSymbolicLinkPath(const char *strName,char *strPath,UINT nlenPath);
BOOL ListSymlink(CStringArray& files); BOOL ListSymlink(CStringArray& files);
const char * NetbiosName(void);
#endif //__GUI2FS_H__ #endif //__GUI2FS_H__

View File

@ -44,10 +44,9 @@ static BOOL IsWindowsNT (void)
} }
void SetHelpPath(LPCTSTR pszDefaultHelpFilePath)
void SetHelpPath(const char *pszDefaultHelpFilePath)
{ {
CString str = pszDefaultHelpFilePath; CString str(pszDefaultHelpFilePath);
int nIndex = str.ReverseFind('\\'); int nIndex = str.ReverseFind('\\');
ASSERT(nIndex >= 0); ASSERT(nIndex >= 0);

View File

@ -34,6 +34,6 @@
#define EDIT_PATH_NAME_HELP_ID 46 #define EDIT_PATH_NAME_HELP_ID 46
#define SYMLINK_HELP_ID 47 #define SYMLINK_HELP_ID 47
void SetHelpPath(const char *pszDefaultHelpFilePath); void SetHelpPath(LPCTSTR pszDefaultHelpFilePath);
void ShowHelp(HWND hWnd, DWORD nHelpID); void ShowHelp(HWND hWnd, DWORD nHelpID);

View File

@ -15,7 +15,7 @@ typedef class HOURGLASS
HCURSOR m_OldCursor; HCURSOR m_OldCursor;
public: public:
HOURGLASS (LPCSTR idCursor = IDC_WAIT) HOURGLASS (LPTSTR idCursor = IDC_WAIT)
{ {
m_OldCursor = GetCursor(); m_OldCursor = GetCursor();
SetCursor (LoadCursor (NULL, idCursor)); SetCursor (LoadCursor (NULL, idCursor));

View File

@ -31,17 +31,31 @@ extern "C" {
static char THIS_FILE[] = __FILE__; static char THIS_FILE[] = __FILE__;
#endif #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) #define PCCHAR(str) ((char *)(const char *)str)
#endif
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// CKlogDlg dialog // 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; 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*/) CKlogDlg::CKlogDlg(CWnd* pParent /*=NULL*/)
@ -88,7 +102,7 @@ BOOL CKlogDlg::OnInitDialog()
char defaultCell[256]; char defaultCell[256];
long code = cm_GetRootCellName(defaultCell); long code = cm_GetRootCellName(defaultCell);
if (code < 0) if (code < 0)
AfxMessageBox("Error determining root cell name."); AfxMessageBox(_T("Error determining root cell name."));
else else
m_strCellName = defaultCell; m_strCellName = defaultCell;
} }
@ -107,7 +121,8 @@ void CKlogDlg::OnOK()
HOURGLASS hg; HOURGLASS hg;
if (kl_Authenticate(m_strCellName, m_strName, m_strPassword, &reason)) { if (kl_Authenticate(m_strCellName, m_strName, m_strPassword, &reason)) {
AfxMessageBox(reason); CString strReason(reason);
AfxMessageBox(strReason);
return; return;
} }

View File

@ -16,7 +16,7 @@ extern "C" {
#include <afs/stds.h> #include <afs/stds.h>
} }
#include <string.h> #include <tchar.h>
#include <stdarg.h> #include <stdarg.h>
#include "msgs.h" #include "msgs.h"
@ -61,134 +61,134 @@ extern "C" {
UINT ShowMessageBox (UINT Id, UINT Button, UINT Help, ...) { UINT ShowMessageBox (UINT Id, UINT Button, UINT Help, ...) {
CString temp; CString temp;
char *pszstring, TCHAR *pszstring,
*pszpaste, *pszpaste,
*pszcut, *pszcut,
*pszdone, *pszdone,
*pszconvert; *pszconvert;
char chread; TCHAR chread;
va_list params; va_list params;
int x; int x;
pszconvert = new char[255]; pszconvert = new TCHAR[255];
va_start(params, Help); va_start(params, Help);
LoadString (temp, Id); LoadString (temp, Id);
pszstring = temp.GetBuffer(512); pszstring = temp.GetBuffer(512);
strcpy(pszstring,pszstring); _tcscpy(pszstring,pszstring);
temp.ReleaseBuffer(); temp.ReleaseBuffer();
// Look and see - is there a need to insert chars (95% of the time, there won't) // 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; delete pszconvert;
return AfxMessageBox(pszstring, Button, Help); return AfxMessageBox(pszstring, Button, Help);
} }
x = strcspn(pszstring, "%"); x = _tcscspn(pszstring, _T("%"));
pszdone = new char[512]; pszdone = new TCHAR[512];
pszcut = new char[512]; pszcut = new TCHAR[512];
pszpaste = new char[512]; pszpaste = new TCHAR[512];
strcpy(pszcut, &pszstring[x+2]); _tcscpy(pszcut, &pszstring[x+2]);
strncpy(pszpaste, pszstring, x); _tcsncpy(pszpaste, pszstring, x);
pszpaste[x] = '\0'; pszpaste[x] = _T('\0');
chread = pszstring[x+1]; chread = pszstring[x+1];
for ( ; ; ) { for ( ; ; ) {
switch (chread) { switch (chread) {
case 'i' : case _T('i') :
case 'd' : case _T('d') :
{ {
int anint = va_arg(params, int); int anint = va_arg(params, int);
_itoa( anint, pszconvert, 10); _itot( anint, pszconvert, 10);
break; break;
} }
case 'u' : case _T('u') :
{ {
UINT anuint = va_arg(params, UINT); UINT anuint = va_arg(params, UINT);
_itoa( anuint, pszconvert, 10); _itot( anuint, pszconvert, 10);
break; break;
} }
case 'x' : case _T('x') :
case 'X' : case _T('X') :
{ {
int ahex = va_arg(params, int); int ahex = va_arg(params, int);
_itoa( ahex, pszconvert, 16); _itot( ahex, pszconvert, 16);
break; break;
} }
case 'g' : case _T('g') :
case 'f' : case _T('f') :
case 'e' : case _T('e') :
{ {
double adbl = va_arg(params, double); double adbl = va_arg(params, double);
_gcvt( adbl, 10, pszconvert); _stprintf(pszconvert, _T("%g"), adbl);
break; break;
} }
case 's' : case _T('s') :
{ {
char *pStr = va_arg(params, char*); TCHAR *pStr = va_arg(params, TCHAR*);
ASSERT(strlen(pStr) <= 255); ASSERT(_tcslen(pStr) <= 255);
strcpy(pszconvert, pStr); _tcscpy(pszconvert, pStr);
break; break;
} }
case 'l' : case _T('l') :
{ {
chread = pszdone[x+2]; chread = pszdone[x+2];
switch(chread) { switch(chread) {
case 'x' : case _T('x') :
{ {
long int alhex = va_arg(params, long int); long int alhex = va_arg(params, long int);
_ltoa(alhex, pszconvert, 16); _ltot(alhex, pszconvert, 16);
strcpy(pszcut, &pszcut[1]); _tcscpy(pszcut, &pszcut[1]);
break; break;
} }
case 'd' : case _T('d') :
default : default :
{ {
long int along = va_arg(params, long int); 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, // For the L, there will be one character after it,
// so move ahead another letter // so move ahead another letter
strcpy(pszcut, &pszcut[1]); _tcscpy(pszcut, &pszcut[1]);
break; break;
} }
} }
break; break;
} }
case 'c' : case _T('c') :
{ {
int letter = va_arg(params, int); int letter = va_arg(params, int);
pszconvert[0] = (char)letter; pszconvert[0] = (TCHAR)letter;
pszconvert[1] = '\0'; pszconvert[1] = '\0';
break; break;
} }
case 'a' : case _T('a') :
{ {
CString zeta; CString zeta;
char* lsc; TCHAR* lsc;
UINT ls = va_arg(params, UINT); UINT ls = va_arg(params, UINT);
LoadString (zeta, ls); LoadString (zeta, ls);
lsc = zeta.GetBuffer(255); lsc = zeta.GetBuffer(255);
strcpy(pszconvert, lsc); _tcscpy(pszconvert, lsc);
zeta.ReleaseBuffer(); zeta.ReleaseBuffer();
break; break;
} }
case 'o' : case _T('o') :
{ {
CString get = va_arg(params, CString); CString get = va_arg(params, CString);
char* ex = get.GetBuffer(255); TCHAR* ex = get.GetBuffer(255);
strcpy(pszconvert,ex); _tcscpy(pszconvert,ex);
get.ReleaseBuffer(); get.ReleaseBuffer();
break; break;
} }
default : 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; delete pszdone;
pszdone = new char[strlen(pszpaste)+strlen(pszcut)+strlen(pszconvert)+5]; pszdone = new TCHAR[_tcslen(pszpaste)+_tcslen(pszcut)+_tcslen(pszconvert)+5];
strcpy(pszdone, pszpaste); _tcscpy(pszdone, pszpaste);
strcat(pszdone, pszconvert); _tcscat(pszdone, pszconvert);
strcat(pszdone, pszcut); _tcscat(pszdone, pszcut);
AfxMessageBox(pszdone, Button, Help); AfxMessageBox(pszdone, Button, Help);
delete pszcut; delete pszcut;
delete pszpaste; delete pszpaste;
@ -200,14 +200,14 @@ UINT ShowMessageBox (UINT Id, UINT Button, UINT Help, ...) {
} // case } // case
delete pszdone; delete pszdone;
pszdone = new char[strlen(pszpaste)+strlen(pszcut)+strlen(pszconvert)+5]; pszdone = new TCHAR[_tcslen(pszpaste)+_tcslen(pszcut)+_tcslen(pszconvert)+5];
strcpy(pszdone, pszpaste); _tcscpy(pszdone, pszpaste);
strcat(pszdone, pszconvert); _tcscat(pszdone, pszconvert);
strcat(pszdone, pszcut); _tcscat(pszdone, pszcut);
// Now pszdone holds the entire message. // Now pszdone holds the entire message.
// Check to see if there are more insertions to be made or not // 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); UINT rt_type = AfxMessageBox(pszdone, Button, Help);
delete pszcut; delete pszcut;
delete pszpaste; delete pszpaste;
@ -217,10 +217,10 @@ UINT ShowMessageBox (UINT Id, UINT Button, UINT Help, ...) {
} // if } // if
// there are more insertions to make, prepare the strings to use. // there are more insertions to make, prepare the strings to use.
x = strcspn(pszdone, "%"); x = _tcscspn(pszdone, _T("%"));
strcpy(pszcut, &pszdone[x+2]); _tcscpy(pszcut, &pszdone[x+2]);
strncpy(pszpaste, pszdone, x); _tcsncpy(pszpaste, pszdone, x);
pszpaste[x] = '\0'; pszpaste[x] = _T('\0');
chread = pszdone[x+1]; chread = pszdone[x+1];
} // for } // for
@ -232,137 +232,137 @@ UINT ShowMessageBox (UINT Id, UINT Button, UINT Help, ...) {
CString GetMessageString(UINT Id, ...) CString GetMessageString(UINT Id, ...)
{ {
CString temp; CString temp;
char *pszstring, TCHAR *pszstring,
*pszpaste, *pszpaste,
*pszcut, *pszcut,
*pszdone, *pszdone,
*pszconvert; *pszconvert;
char chread; TCHAR chread;
va_list params; va_list params;
int x; int x;
CString strMsg; CString strMsg;
pszconvert = new char[255]; pszconvert = new TCHAR[255];
va_start(params, Id); va_start(params, Id);
LoadString (temp, Id); LoadString (temp, Id);
pszstring = temp.GetBuffer(512); pszstring = temp.GetBuffer(512);
strcpy(pszconvert,pszstring); _tcscpy(pszconvert,pszstring);
temp.ReleaseBuffer(); temp.ReleaseBuffer();
// Look and see - is there a need to insert chars (95% of the time, there won't) // 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; strMsg = pszconvert;
delete pszconvert; delete pszconvert;
return strMsg; return strMsg;
} }
x = strcspn(pszstring, "%"); x = _tcscspn(pszstring, _T("%"));
pszdone = new char[512]; pszdone = new TCHAR[512];
pszcut = new char[512]; pszcut = new TCHAR[512];
pszpaste = new char[512]; pszpaste = new TCHAR[512];
strcpy(pszcut, &pszstring[x+2]); _tcscpy(pszcut, &pszstring[x+2]);
strncpy(pszpaste, pszstring, x); _tcsncpy(pszpaste, pszstring, x);
pszpaste[x] = '\0'; pszpaste[x] = _T('\0');
chread = pszstring[x+1]; chread = pszstring[x+1];
for ( ; ; ) { for ( ; ; ) {
switch (chread) { switch (chread) {
case 'i' : case _T('i') :
case 'd' : case _T('d') :
{ {
int anint = va_arg(params, int); int anint = va_arg(params, int);
_itoa( anint, pszconvert, 10); _itot( anint, pszconvert, 10);
break; break;
} }
case 'u' : case _T('u') :
{ {
UINT anuint = va_arg(params, UINT); UINT anuint = va_arg(params, UINT);
_itoa( anuint, pszconvert, 10); _itot( anuint, pszconvert, 10);
break; break;
} }
case 'x' : case _T('x') :
case 'X' : case _T('X') :
{ {
int ahex = va_arg(params, int); int ahex = va_arg(params, int);
_itoa( ahex, pszconvert, 16); _itot( ahex, pszconvert, 16);
break; break;
} }
case 'g' : case _T('g') :
case 'f' : case _T('f') :
case 'e' : case _T('e') :
{ {
double adbl = va_arg(params, double); double adbl = va_arg(params, double);
_gcvt( adbl, 10, pszconvert); _stprintf(pszconvert, _T("%g"), adbl);
break; break;
} }
case 's' : case _T('s') :
{ {
char *pStr = va_arg(params, char*); TCHAR *pStr = va_arg(params, TCHAR*);
ASSERT(strlen(pStr) <= 255); ASSERT(_tcslen(pStr) <= 255);
strcpy(pszconvert, pStr); _tcscpy(pszconvert, pStr);
break; break;
} }
case 'l' : case _T('l') :
{ {
chread = pszdone[x+2]; chread = pszdone[x+2];
switch(chread) { switch(chread) {
case 'x' : case _T('x') :
{ {
long int alhex = va_arg(params, long int); long int alhex = va_arg(params, long int);
_ltoa(alhex, pszconvert, 16); _ltot(alhex, pszconvert, 16);
strcpy(pszcut, &pszcut[1]); _tcscpy(pszcut, &pszcut[1]);
break; break;
} }
case 'd' : case _T('d') :
default : default :
{ {
long int along = va_arg(params, long int); 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, // For the L, there will be one character after it,
// so move ahead another letter // so move ahead another letter
strcpy(pszcut, &pszcut[1]); _tcscpy(pszcut, &pszcut[1]);
break; break;
} }
} }
break; break;
} }
case 'c' : case _T('c') :
{ {
int letter = va_arg(params, int); int letter = va_arg(params, int);
pszconvert[0] = (char)letter; pszconvert[0] = (TCHAR)letter;
pszconvert[1] = '\0'; pszconvert[1] = _T('\0');
break; break;
} }
case 'a' : case _T('a') :
{ {
CString zeta; CString zeta;
char* lsc; TCHAR* lsc;
UINT ls = va_arg(params, UINT); UINT ls = va_arg(params, UINT);
LoadString (zeta, ls); LoadString (zeta, ls);
lsc = zeta.GetBuffer(255); lsc = zeta.GetBuffer(255);
strcpy(pszconvert, lsc); _tcscpy(pszconvert, lsc);
zeta.ReleaseBuffer(); zeta.ReleaseBuffer();
break; break;
} }
case 'o' : case _T('o') :
{ {
CString get = va_arg(params, CString); CString get = va_arg(params, CString);
char* ex = get.GetBuffer(255); TCHAR* ex = get.GetBuffer(255);
strcpy(pszconvert,ex); _tcscpy(pszconvert,ex);
get.ReleaseBuffer(); get.ReleaseBuffer();
break; break;
} }
default: 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; delete pszdone;
pszdone = new char[strlen(pszpaste)+strlen(pszcut)+strlen(pszconvert)+5]; pszdone = new TCHAR[_tcslen(pszpaste)+_tcslen(pszcut)+_tcslen(pszconvert)+5];
strcpy(pszdone, pszpaste); _tcscpy(pszdone, pszpaste);
strcat(pszdone, pszconvert); _tcscat(pszdone, pszconvert);
strcat(pszdone, pszcut); _tcscat(pszdone, pszcut);
strMsg = pszdone; strMsg = pszdone;
delete pszcut; delete pszcut;
delete pszpaste; delete pszpaste;
@ -374,14 +374,14 @@ CString GetMessageString(UINT Id, ...)
} // case } // case
delete pszdone; delete pszdone;
pszdone = new char[strlen(pszpaste)+strlen(pszcut)+strlen(pszconvert)+5]; pszdone = new TCHAR[_tcslen(pszpaste)+_tcslen(pszcut)+_tcslen(pszconvert)+5];
strcpy(pszdone, pszpaste); _tcscpy(pszdone, pszpaste);
strcat(pszdone, pszconvert); _tcscat(pszdone, pszconvert);
strcat(pszdone, pszcut); _tcscat(pszdone, pszcut);
// Now pszdone holds the entire message. // Now pszdone holds the entire message.
// Check to see if there are more insertions to be made or not // Check to see if there are more insertions to be made or not
if (!strstr(pszdone, "%")) { if (!_tcsstr(pszdone, _T("%"))) {
strMsg = pszdone; strMsg = pszdone;
delete pszcut; delete pszcut;
delete pszpaste; delete pszpaste;
@ -391,10 +391,10 @@ CString GetMessageString(UINT Id, ...)
} // if } // if
// there are more insertions to make, prepare the strings to use. // there are more insertions to make, prepare the strings to use.
x = strcspn(pszdone, "%"); x = _tcscspn(pszdone, _T("%"));
strcpy(pszcut, &pszdone[x+2]); _tcscpy(pszcut, &pszdone[x+2]);
strncpy(pszpaste, pszdone, x); _tcsncpy(pszpaste, pszdone, x);
pszpaste[x] = '\0'; pszpaste[x] = _T('\0');
chread = pszdone[x+1]; chread = pszdone[x+1];
} // for } // for
@ -404,8 +404,15 @@ CString GetMessageString(UINT Id, ...)
void LoadString (CString &Str, UINT id) 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); GetString (szString, id);
#ifdef UNICODE
CString wstr(szString);
Str = wstr;
#else
Str = szString; Str = szString;
#endif
} }

View File

@ -69,18 +69,18 @@ BOOL CPartitionInfoDlg::OnInitDialog()
ASSERT(m_nSize != 0); ASSERT(m_nSize != 0);
CString strSize; CString strSize;
strSize.Format("%ld", m_nSize); strSize.Format(_T("%ld"), m_nSize);
CString strFree; CString strFree;
strFree.Format("%ld", m_nFree); strFree.Format(_T("%ld"), m_nFree);
CString strPerUsed; 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_Size.SetWindowText(strSize);
m_Free.SetWindowText(strFree); m_Free.SetWindowText(strFree);
percentUsed = ( double(m_nSize - m_nFree) * 100.0l ) / double(m_nSize); 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 return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE // EXCEPTION: OCX Property Pages should return FALSE

View File

@ -104,10 +104,10 @@ BOOL CSetAfsAcl::OnInitDialog()
int i; int i;
for (i = 0; i < m_Normal.GetSize(); i += 2) 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) 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(); CenterWindow();
@ -162,13 +162,13 @@ void CSetAfsAcl::OnAdd()
if (bNormal) { if (bNormal) {
m_Normal.Add(name); m_Normal.Add(name);
m_Normal.Add(rights); 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_NormalRights.SetSel(m_nCurSel);
m_bShowingNormal = TRUE; m_bShowingNormal = TRUE;
} else { } else {
m_Negative.Add(name); m_Negative.Add(name);
m_Negative.Add(rights); 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_NegativeRights.SetSel(m_nCurSel);
m_bShowingNormal = FALSE; m_bShowingNormal = FALSE;
} }
@ -196,13 +196,13 @@ void CSetAfsAcl::OnCopy()
void CSetAfsAcl::ShowRights(const CString& strRights) void CSetAfsAcl::ShowRights(const CString& strRights)
{ {
m_ReadPerm.SetCheck((strRights.Find("r") == -1) ? UNCHECKED : CHECKED); m_ReadPerm.SetCheck((strRights.Find(_T("r")) == -1) ? UNCHECKED : CHECKED);
m_WritePerm.SetCheck((strRights.Find("w") == -1) ? UNCHECKED : CHECKED); m_WritePerm.SetCheck((strRights.Find(_T("w")) == -1) ? UNCHECKED : CHECKED);
m_LookupPerm.SetCheck((strRights.Find("l") == -1) ? UNCHECKED : CHECKED); m_LookupPerm.SetCheck((strRights.Find(_T("l")) == -1) ? UNCHECKED : CHECKED);
m_DeletePerm.SetCheck((strRights.Find("d") == -1) ? UNCHECKED : CHECKED); m_DeletePerm.SetCheck((strRights.Find(_T("d")) == -1) ? UNCHECKED : CHECKED);
m_InsertPerm.SetCheck((strRights.Find("i") == -1) ? UNCHECKED : CHECKED); m_InsertPerm.SetCheck((strRights.Find(_T("i")) == -1) ? UNCHECKED : CHECKED);
m_LockPerm.SetCheck((strRights.Find("k") == -1) ? UNCHECKED : CHECKED); m_LockPerm.SetCheck((strRights.Find(_T("k")) == -1) ? UNCHECKED : CHECKED);
m_AdminPerm.SetCheck((strRights.Find("a") == -1) ? UNCHECKED : CHECKED); m_AdminPerm.SetCheck((strRights.Find(_T("a")) == -1) ? UNCHECKED : CHECKED);
} }
void CSetAfsAcl::OnSelChangeNormalRights() void CSetAfsAcl::OnSelChangeNormalRights()
@ -213,7 +213,7 @@ void CSetAfsAcl::OnSelChangeNormalRights()
int nNum = m_NormalRights.GetSelCount(); int nNum = m_NormalRights.GetSelCount();
if (nNum != 1) { if (nNum != 1) {
ShowRights(""); ShowRights(_T(""));
EnablePermChanges(FALSE); EnablePermChanges(FALSE);
return; return;
} }
@ -236,7 +236,7 @@ void CSetAfsAcl::OnSelChangeNegativeEntries()
int nNum = m_NegativeRights.GetSelCount(); int nNum = m_NegativeRights.GetSelCount();
if (nNum != 1) { if (nNum != 1) {
ShowRights(""); ShowRights(_T(""));
EnablePermChanges(FALSE); EnablePermChanges(FALSE);
return; return;
} }
@ -256,19 +256,19 @@ CString CSetAfsAcl::MakeRightsString()
CString str; CString str;
if (m_ReadPerm.GetCheck() == CHECKED) if (m_ReadPerm.GetCheck() == CHECKED)
str += "r"; str += _T("r");
if (m_LookupPerm.GetCheck() == CHECKED) if (m_LookupPerm.GetCheck() == CHECKED)
str += "l"; str += _T("l");
if (m_InsertPerm.GetCheck() == CHECKED) if (m_InsertPerm.GetCheck() == CHECKED)
str += "i"; str += _T("i");
if (m_DeletePerm.GetCheck() == CHECKED) if (m_DeletePerm.GetCheck() == CHECKED)
str += "d"; str += _T("d");
if (m_WritePerm.GetCheck() == CHECKED) if (m_WritePerm.GetCheck() == CHECKED)
str += "w"; str += _T("w");
if (m_LockPerm.GetCheck() == CHECKED) if (m_LockPerm.GetCheck() == CHECKED)
str += "k"; str += _T("k");
if (m_AdminPerm.GetCheck() == CHECKED) if (m_AdminPerm.GetCheck() == CHECKED)
str += "a"; str += _T("a");
return str; return str;
} }
@ -290,7 +290,7 @@ void CSetAfsAcl::OnPermChange()
CString str = MakeRightsString(); CString str = MakeRightsString();
(*pRights)[(2 * m_nCurSel) + 1] = str; (*pRights)[(2 * m_nCurSel) + 1] = str;
str += "\t" + (*pRights)[(2 * m_nCurSel)]; str += _T("\t") + (*pRights)[(2 * m_nCurSel)];
pRightsList->DeleteString(m_nCurSel); pRightsList->DeleteString(m_nCurSel);
pRightsList->InsertString(m_nCurSel, str); pRightsList->InsertString(m_nCurSel, str);
@ -364,7 +364,7 @@ void CSetAfsAcl::OnNothingSelected()
{ {
m_NegativeRights.SetSel(i, FALSE); m_NegativeRights.SetSel(i, FALSE);
} }
ShowRights(""); // Show no rights ShowRights(_T("")); // Show no rights
EnablePermChanges(FALSE); // Allow no rights changes EnablePermChanges(FALSE); // Allow no rights changes
m_Remove.EnableWindow(FALSE); // Disable remove button m_Remove.EnableWindow(FALSE); // Disable remove button
} }

View File

@ -54,7 +54,7 @@ static BOOL IsADir(const CString& strName)
{ {
struct _stat statbuf; struct _stat statbuf;
if (_stat(strName, &statbuf) < 0) if (_tstat(strName, &statbuf) < 0)
return FALSE; return FALSE;
return statbuf.st_mode & _S_IFDIR; return statbuf.st_mode & _S_IFDIR;
@ -79,9 +79,9 @@ CShellExt::CShellExt()
m_bIsOverlayEnabled=FALSE; m_bIsOverlayEnabled=FALSE;
if (FAILED(hr)) if (FAILED(hr))
m_pAlloc = NULL; 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); LSPsize=sizeof(ShellOption);
code=RegQueryValueEx(NPKey, "ShellOption", NULL, code=RegQueryValueEx(NPKey, _T("ShellOption"), NULL,
&LSPtype, (LPBYTE)&ShellOption, &LSPsize); &LSPtype, (LPBYTE)&ShellOption, &LSPsize);
RegCloseKey (NPKey); RegCloseKey (NPKey);
m_bIsOverlayEnabled=((code==0) && (LSPtype==REG_DWORD) && ((ShellOption & OVERLAYENABLED)!=0)); m_bIsOverlayEnabled=((code==0) && (LSPtype==REG_DWORD) && ((ShellOption & OVERLAYENABLED)!=0));
@ -206,11 +206,11 @@ STDMETHODIMP CShellExt::XMenuExt::QueryContextMenu(HMENU hMenu,UINT indexMenu,
DeleteMenu (hMenu, iItem, MF_BYPOSITION); DeleteMenu (hMenu, iItem, MF_BYPOSITION);
continue; 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); DeleteMenu (hMenu, iItem, MF_BYPOSITION);
continue; 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); DeleteMenu (hMenu, iItem, MF_BYPOSITION);
continue; continue;
} }
@ -411,7 +411,7 @@ STDMETHODIMP CShellExt::XMenuExt::InvokeCommand(LPCMINVOKECOMMANDINFO lpici)
} }
case IDM_SYMBOLICLINK_ADD: { case IDM_SYMBOLICLINK_ADD: {
CString msg=files.GetAt(0); CStringA msg(files.GetAt(0));
int i; int i;
if ((i=msg.ReverseFind('\\'))>0) if ((i=msg.ReverseFind('\\'))>0)
msg=msg.Left(i+1); msg=msg.Left(i+1);
@ -531,7 +531,7 @@ STDMETHODIMP CShellExt::XMenuExt::GetCommandString(UINT_PTR idCmd, UINT uType,
CString strMsg; CString strMsg;
LoadString (strMsg, nCmdStrID); LoadString (strMsg, nCmdStrID);
strncpy(pszName, strMsg, cchMax); _tcsncpy((LPTSTR) pszName, strMsg, cchMax);
return NOERROR; return NOERROR;
} }
@ -658,10 +658,14 @@ STDMETHODIMP CShellExt::XIconExt::GetOverlayInfo(LPWSTR pwszIconFile
if(IsBadWritePtr(pdwFlags, sizeof(DWORD))) if(IsBadWritePtr(pdwFlags, sizeof(DWORD)))
return E_INVALIDARG; return E_INVALIDARG;
HMODULE hModule=GetModuleHandle("shell32.dll"); HMODULE hModule=GetModuleHandle(_T("shell32.dll"));
TCHAR szModule[MAX_PATH]; TCHAR szModule[MAX_PATH];
DWORD z=GetModuleFileName(hModule,szModule,sizeof(szModule)); DWORD z=GetModuleFileName(hModule,szModule,sizeof(szModule));
#ifndef UNICODE
MultiByteToWideChar( CP_ACP,0,szModule,-1,pwszIconFile,cchMax); MultiByteToWideChar( CP_ACP,0,szModule,-1,pwszIconFile,cchMax);
#else
_tcsncpy(pwszIconFile, szModule, cchMax);
#endif
*pIndex = 30; *pIndex = 30;
*pdwFlags = ISIOI_ICONFILE | ISIOI_ICONINDEX; *pdwFlags = ISIOI_ICONFILE | ISIOI_ICONINDEX;
return S_OK; return S_OK;
@ -678,7 +682,11 @@ STDMETHODIMP CShellExt::XIconExt::GetPriority(int* pPriority)
STDMETHODIMP CShellExt::XIconExt::IsMemberOf(LPCWSTR pwszPath,DWORD dwAttrib) STDMETHODIMP CShellExt::XIconExt::IsMemberOf(LPCWSTR pwszPath,DWORD dwAttrib)
{ {
TCHAR szPath[MAX_PATH]; TCHAR szPath[MAX_PATH];
#ifdef UNICODE
_tcscpy(szPath, pwszPath);
#else
WideCharToMultiByte( CP_ACP,0,pwszPath,-1,szPath,MAX_PATH,NULL,NULL); WideCharToMultiByte( CP_ACP,0,pwszPath,-1,szPath,MAX_PATH,NULL,NULL);
#endif
if (IsSymlink(szPath)) if (IsSymlink(szPath))
return S_OK; return S_OK;
return S_FALSE; return S_FALSE;

View File

@ -24,7 +24,7 @@ extern ULONG nICRefCount; // IContextMenu ref count
extern ULONG nTPRefCount; // IQueryInfo ref count extern ULONG nTPRefCount; // IQueryInfo ref count
extern ULONG nXPRefCount; // IPersistFile 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") #define STR_REG_PATH TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ShellIconOverlayIdentifiers")
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////

View File

@ -45,10 +45,10 @@ static CSubmountInfo *ReadSubmtInfo(const CString& strShareName)
DWORD len; DWORD len;
char pathName[1024]; TCHAR pathName[1024];
HKEY hkSubmounts; HKEY hkSubmounts;
RegCreateKeyEx( HKEY_LOCAL_MACHINE, RegCreateKeyExA( HKEY_LOCAL_MACHINE,
AFSREG_CLT_OPENAFS_SUBKEY "\\Submounts", AFSREG_CLT_OPENAFS_SUBKEY "\\Submounts",
0, 0,
"AFS", "AFS",
@ -61,7 +61,7 @@ static CSubmountInfo *ReadSubmtInfo(const CString& strShareName)
DWORD dwType; DWORD dwType;
DWORD status; DWORD status;
len = sizeof(pathName); len = sizeof(pathName);
status = RegQueryValueEx( hkSubmounts, (LPCSTR)PCCHAR(strShareName), 0, status = RegQueryValueEx( hkSubmounts, strShareName, 0,
&dwType, (LPBYTE)pathName, &len); &dwType, (LPBYTE)pathName, &len);
RegCloseKey( hkSubmounts ); RegCloseKey( hkSubmounts );
@ -169,7 +169,7 @@ BOOL CSubmountsDlg::FillSubmtList()
DWORD dwIndex; DWORD dwIndex;
DWORD dwSubmounts; DWORD dwSubmounts;
RegCreateKeyEx( HKEY_LOCAL_MACHINE, RegCreateKeyExA( HKEY_LOCAL_MACHINE,
AFSREG_CLT_OPENAFS_SUBKEY "\\Submounts", AFSREG_CLT_OPENAFS_SUBKEY "\\Submounts",
0, 0,
"AFS", "AFS",
@ -195,7 +195,7 @@ BOOL CSubmountsDlg::FillSubmtList()
for ( dwIndex = 0; dwIndex < dwSubmounts; dwIndex ++ ) { for ( dwIndex = 0; dwIndex < dwSubmounts; dwIndex ++ ) {
char submountName[256]; TCHAR submountName[256];
DWORD submountNameLen = sizeof(submountName); DWORD submountNameLen = sizeof(submountName);
RegEnumValue( hkSubmounts, dwIndex, submountName, &submountNameLen, NULL, RegEnumValue( hkSubmounts, dwIndex, submountName, &submountNameLen, NULL,
@ -222,7 +222,7 @@ void CSubmountsDlg::OnDelete()
ASSERT(!strSubmt.IsEmpty()); 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) if (ShowMessageBox(IDS_REALLY_DELETE_SUBMT, MB_YESNO | MB_ICONQUESTION, IDS_REALLY_DELETE_SUBMT, strShareName) != IDYES)
return; return;
@ -251,7 +251,7 @@ static BOOL AddSubmt(CSubmountInfo *pInfo)
HOURGLASS hourglass; HOURGLASS hourglass;
HKEY hkSubmounts; HKEY hkSubmounts;
RegCreateKeyEx( HKEY_LOCAL_MACHINE, RegCreateKeyExA( HKEY_LOCAL_MACHINE,
AFSREG_CLT_OPENAFS_SUBKEY "\\Submounts", AFSREG_CLT_OPENAFS_SUBKEY "\\Submounts",
0, 0,
"AFS", "AFS",
@ -261,8 +261,9 @@ static BOOL AddSubmt(CSubmountInfo *pInfo)
&hkSubmounts, &hkSubmounts,
NULL ); NULL );
DWORD status = RegSetValueEx( hkSubmounts, PCCHAR(pInfo->GetShareName()), 0, REG_SZ, DWORD status = RegSetValueEx( hkSubmounts, pInfo->GetShareName(), 0, REG_SZ,
(const BYTE *)PCCHAR(pInfo->GetPathName()), strlen(PCCHAR(pInfo->GetPathName())) + 1); (const BYTE *)(const TCHAR *) pInfo->GetPathName(),
pInfo->GetPathName().GetLength() + 1);
RegCloseKey(hkSubmounts); RegCloseKey(hkSubmounts);
return (status == ERROR_SUCCESS); return (status == ERROR_SUCCESS);
@ -273,7 +274,7 @@ static BOOL DeleteSubmt(CSubmountInfo *pInfo)
HOURGLASS hourglass; HOURGLASS hourglass;
HKEY hkSubmounts; HKEY hkSubmounts;
RegCreateKeyEx( HKEY_LOCAL_MACHINE, RegCreateKeyExA( HKEY_LOCAL_MACHINE,
AFSREG_CLT_OPENAFS_SUBKEY "\\Submounts", AFSREG_CLT_OPENAFS_SUBKEY "\\Submounts",
0, 0,
"AFS", "AFS",
@ -283,7 +284,7 @@ static BOOL DeleteSubmt(CSubmountInfo *pInfo)
&hkSubmounts, &hkSubmounts,
NULL ); NULL );
DWORD status = RegDeleteValue( hkSubmounts, PCCHAR(pInfo->GetShareName())); DWORD status = RegDeleteValue( hkSubmounts, pInfo->GetShareName());
RegCloseKey(hkSubmounts); RegCloseKey(hkSubmounts);
return (status == ERROR_SUCCESS); return (status == ERROR_SUCCESS);
@ -325,7 +326,7 @@ void CSubmountsDlg::OnChange()
ASSERT(!strSubmt.IsEmpty()); ASSERT(!strSubmt.IsEmpty());
strShareName = strSubmt.SpanExcluding("="); strShareName = strSubmt.SpanExcluding(_T("="));
CSubmountInfo *pInfo = FindWork(strShareName); CSubmountInfo *pInfo = FindWork(strShareName);
if (pInfo != 0) if (pInfo != 0)

View File

@ -69,7 +69,7 @@ BOOL CUnlogDlg::OnInitDialog()
char defaultCell[256]; char defaultCell[256];
long code = cm_GetRootCellName(defaultCell); long code = cm_GetRootCellName(defaultCell);
if (code < 0) if (code < 0)
AfxMessageBox("Error determining root cell name."); AfxMessageBox(_T("Error determining root cell name."));
else else
m_strCellName = defaultCell; m_strCellName = defaultCell;
} }
@ -83,21 +83,24 @@ int kl_Unlog(const CString& strCellName)
{ {
struct ktc_principal server; struct ktc_principal server;
int code; int code;
static char xreason[100];
if (strCellName.IsEmpty()) if (strCellName.IsEmpty())
code = ktc_ForgetAllTokens(); code = ktc_ForgetAllTokens();
else { else {
strcpy(server.cell, strCellName); CStringA astrCellName(strCellName);
strcpy(server.cell, astrCellName);
server.instance[0] = '\0'; server.instance[0] = '\0';
strcpy(server.name, "afs"); strcpy(server.name, "afs");
code = ktc_ForgetToken(&server); code = ktc_ForgetToken(&server);
} }
if (code == KTC_NOCM) if (code == KTC_NOCM)
AfxMessageBox("AFS service may not have started"); AfxMessageBox(_T("AFS service may not have started"));
else if (code) { else if (code) {
sprintf(xreason, "Unexpected error, code %d", code); CString xreason;
xreason.Format(_T("Unexpected error, code %d"), code);
AfxMessageBox(xreason); AfxMessageBox(xreason);
} }

View File

@ -233,10 +233,15 @@ void CVolumeInfo::ShowInfo()
if (nQuota != 0) { if (nQuota != 0) {
LONG nPercentUsed = (m_pVolInfo[i].m_nUsed * 100) / nQuota; 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, strEntry.Format(_T("%s\t%s\t%ld\t%ldK\t%ldK\t%ld%%"),
m_pVolInfo[i].m_nID, nQuota, m_pVolInfo[i].m_nUsed, nPercentUsed); m_pVolInfo[i].m_strFileName,
m_pVolInfo[i].m_strName,
m_pVolInfo[i].m_nID, nQuota,
m_pVolInfo[i].m_nUsed, nPercentUsed);
} else { } 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); m_pVolInfo[i].m_nID, m_pVolInfo[i].m_nUsed);
} }
} }

View File

@ -37,6 +37,10 @@
#sanity checks #sanity checks
!IF ("$(CPU)" != "x86")
CPU=i386
!ENDIF
!IF ("$(CPU)" != "i386") !IF ("$(CPU)" != "i386")
!ERROR Platform SDK not configured for i386 !ERROR Platform SDK not configured for i386
!ENDIF !ENDIF
@ -82,7 +86,7 @@ INCLUDE = $(AFSDEV_INCLUDE)
LIB = $(AFSDEV_LIB) LIB = $(AFSDEV_LIB)
#define used in WinNT/2000 installation and program version display #define used in WinNT/2000 installation and program version display
AFSPRODUCT_VER_MAJOR=0 AFSPRODUCT_VER_MAJOR=2
AFSPRODUCT_VER_MINOR=0 AFSPRODUCT_VER_MINOR=0
AFSPRODUCT_VER_PATCH=0 AFSPRODUCT_VER_PATCH=0
AFSPRODUCT_VER_BUILD=0 AFSPRODUCT_VER_BUILD=0
@ -223,6 +227,7 @@ afscdefs =\
-DAFS_64BIT_ENV \ -DAFS_64BIT_ENV \
-DAFS_64BIT_CLIENT \ -DAFS_64BIT_CLIENT \
-DAFS_LARGEFILE_ENV \ -DAFS_LARGEFILE_ENV \
-DAFS_OLD_COM_ERR \
$(AFSDEV_AUXCDEFINES) $(AFSDEV_AUXCDEFINES)
# Compiler switches (except include paths and preprocessor defines) # Compiler switches (except include paths and preprocessor defines)

View File

@ -115,3 +115,4 @@ EXPORTS
VOTE_GetSyncSite @113 VOTE_GetSyncSite @113
ubik_RefreshConn @114 ubik_RefreshConn @114
rx_SetSecurityConfiguration @115 rx_SetSecurityConfiguration @115
pioctl_utf8 @116

View File

@ -53,6 +53,9 @@ set NTDDKDIR=c:\progra~1\micros~5
REM Location of netmpr.h/netspi.h (from Windows 95/98 DDK - 8.3 short name) REM Location of netmpr.h/netspi.h (from Windows 95/98 DDK - 8.3 short name)
SET W9XDDKDIR=c:\progra~1\micros~6 SET W9XDDKDIR=c:\progra~1\micros~6
REM Location of Microsoft IDN Normalization SDK
set MSIDNNLS=C:\progra~1\MI5913~1
REM ######################################################################## REM ########################################################################
REM NTMakefile optional definitions: REM NTMakefile optional definitions:
REM REM
@ -113,7 +116,7 @@ REM AFSDEV_BIN = default build binary directories
set AFSDEV_BUILDTYPE=%AFSBLD_TYPE% 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%" == "1400" set AFSDEV_INCLUDE=%AFSDEV_INCLUDE%;%MSVCDIR%\atlmfc\include
IF "%AFSVER_CL%" == "1310" 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 IF "%AFSVER_CL%" == "1300" set AFSDEV_INCLUDE=%AFSDEV_INCLUDE%;%MSVCDIR%\atlmfc\include

View File

@ -49,6 +49,9 @@ RCSID
static char AFSConfigKeyName[] = AFSREG_CLT_SVC_PARAM_SUBKEY; 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 #define FS_IOCTLREQUEST_MAXSIZE 8192
/* big structure for representing and storing an IOCTL request */ /* big structure for representing and storing an IOCTL request */
typedef struct fs_ioctlRequest { typedef struct fs_ioctlRequest {
@ -763,7 +766,7 @@ UnmarshallLong(fs_ioctlRequest_t * reqp, long *valp)
/* includes marshalling NULL pointer as a null (0 length) string */ /* includes marshalling NULL pointer as a null (0 length) string */
static long static long
MarshallString(fs_ioctlRequest_t * reqp, char *stringp) MarshallString(fs_ioctlRequest_t * reqp, char *stringp, int is_utf8)
{ {
int count; int count;
@ -772,6 +775,10 @@ MarshallString(fs_ioctlRequest_t * reqp, char *stringp)
else else
count = 1; count = 1;
if (is_utf8) {
count += utf8_prefix_size;
}
/* watch for buffer overflow */ /* watch for buffer overflow */
if ((reqp->mp - reqp->data) + count > sizeof(reqp->data)) { if ((reqp->mp - reqp->data) + count > sizeof(reqp->data)) {
if ( IoctlDebug() ) if ( IoctlDebug() )
@ -779,6 +786,12 @@ MarshallString(fs_ioctlRequest_t * reqp, char *stringp)
return -1; return -1;
} }
if (is_utf8) {
memcpy(reqp->mp, utf8_prefix, utf8_prefix_size);
reqp->mp += utf8_prefix_size;
count -= utf8_prefix_size;
}
if (stringp) if (stringp)
memcpy(reqp->mp, stringp, count); memcpy(reqp->mp, stringp, count);
else else
@ -906,8 +919,8 @@ fs_GetFullPath(char *pathp, char *outPathp, long outSize)
return 0; return 0;
} }
long static long
pioctl(char *pathp, long opcode, struct ViceIoctl *blobp, int follow) pioctl_int(char *pathp, long opcode, struct ViceIoctl *blobp, int follow, int is_utf8)
{ {
fs_ioctlRequest_t preq; fs_ioctlRequest_t preq;
long code; long code;
@ -945,7 +958,7 @@ pioctl(char *pathp, long opcode, struct ViceIoctl *blobp, int follow)
strcpy(fullPath, ""); strcpy(fullPath, "");
} }
MarshallString(&preq, fullPath); MarshallString(&preq, fullPath, is_utf8);
if (blobp->in_size) { if (blobp->in_size) {
if (blobp->in_size > sizeof(preq.data) - (preq.mp - preq.data)*sizeof(char)) { if (blobp->in_size > sizeof(preq.data) - (preq.mp - preq.data)*sizeof(char)) {
errno = E2BIG; errno = E2BIG;
@ -989,3 +1002,16 @@ pioctl(char *pathp, long opcode, struct ViceIoctl *blobp, int follow)
CloseHandle(reqHandle); CloseHandle(reqHandle);
return 0; 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);
}

View File

@ -28,4 +28,7 @@ typedef struct ViceIoctl {
extern long pioctl(char *pathp, long opcode, struct ViceIoctl *blob, extern long pioctl(char *pathp, long opcode, struct ViceIoctl *blob,
int follow); int follow);
extern long pioctl_utf8(char *pathp, long opcode, struct ViceIoctl *blob,
int follow);
#endif /* OPENAFS_AFS_PIOCTL_H */ #endif /* OPENAFS_AFS_PIOCTL_H */