#include <string.h>
#include <winioctl.h>
#include <winsock2.h>
+#define SECURITY_WIN32
+#include <security.h>
#include <nb30.h>
#include <osi.h>
rp->nbytes = 0;
}
+static BOOL
+IoctlDebug(void)
+{
+ static int init = 0;
+ static BOOL debug = 0;
+
+ if ( !init ) {
+ HKEY hk;
+
+ if (RegOpenKey (HKEY_LOCAL_MACHINE,
+ TEXT("Software\\OpenAFS\\Client"), &hk) == 0)
+ {
+ DWORD dwSize = sizeof(BOOL);
+ DWORD dwType = REG_DWORD;
+ RegQueryValueEx (hk, TEXT("IoctlDebug"), NULL, &dwType, (PBYTE)&debug, &dwSize);
+ RegCloseKey (hk);
+ }
+
+ init = 1;
+ }
+
+ return debug;
+}
+
static long
GetIoctlHandle(char *fileNamep, HANDLE * handlep)
{
char netbiosName[MAX_NB_NAME_LENGTH];
char tbuffer[256]="";
HANDLE fh;
+ HKEY hk;
+ char szUser[128] = "";
+ char szClient[MAX_PATH] = "";
+ char szPath[MAX_PATH] = "";
+ NETRESOURCE nr;
+ DWORD res;
+ DWORD ioctlDebug = IoctlDebug();
+ DWORD gle;
+ DWORD dwSize = sizeof(szUser);
if (fileNamep) {
drivep = strchr(fileNamep, ':');
strcat(tbuffer, SMB_IOCTL_FILENAME_NOSLASH);
}
}
- }
- if (!tbuffer[0]) {
+ }
+ if (!tbuffer[0]) {
/* No file name starting with drive colon specified, use UNC name */
lana_GetNetbiosName(netbiosName,LANA_NETBIOS_NAME_FULL);
sprintf(tbuffer,"\\\\%s\\all%s",netbiosName,SMB_IOCTL_FILENAME);
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
FILE_FLAG_WRITE_THROUGH, NULL);
fflush(stdout);
- if (fh == INVALID_HANDLE_VALUE) {
- HKEY hk;
- char szUser[64] = "";
- char szClient[MAX_PATH] = "";
- char szPath[MAX_PATH] = "";
- NETRESOURCE nr;
- DWORD res;
-
- if (GetLastError() != ERROR_DOWNGRADE_DETECTED)
- return -1;
+ if (fh == INVALID_HANDLE_VALUE) {
+ gle = GetLastError();
+ if (gle && ioctlDebug ) {
+ char buf[4096];
+
+ if ( FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL,
+ gle,
+ MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),
+ buf,
+ 4096,
+ (va_list *) NULL
+ ) )
+ {
+ fprintf(stderr,"pioctl CreateFile(%s) failed: 0x%8X\r\n\t[%s]\r\n",
+ tbuffer,gle,buf);
+ }
+ }
+#ifdef COMMENT
+ if (gle != ERROR_DOWNGRADE_DETECTED)
+ return -1;
+#endif
lana_GetNetbiosName(szClient, LANA_NETBIOS_NAME_FULL);
- sprintf(szPath, "\\\\%s", szClient);
- /* We should probably be using GetUserNameEx() for this */
if (RegOpenKey (HKEY_CURRENT_USER,
- TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer"), &hk) == 0)
+ TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer"), &hk) == 0)
{
- DWORD dwSize = sizeof(szUser);
DWORD dwType = REG_SZ;
RegQueryValueEx (hk, TEXT("Logon User Name"), NULL, &dwType, (PBYTE)szUser, &dwSize);
RegCloseKey (hk);
}
- memset (&nr, 0x00, sizeof(NETRESOURCE));
- nr.dwType=RESOURCETYPE_DISK;
- nr.lpLocalName=0;
- nr.lpRemoteName=szPath;
- res = WNetAddConnection2(&nr,NULL,szUser,0);
- if (res)
- return -1;
-
- fh = CreateFile(tbuffer, GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
- FILE_FLAG_WRITE_THROUGH, NULL);
- fflush(stdout);
- if (fh == INVALID_HANDLE_VALUE)
- return -1;
- }
+ if ( szUser[0] ) {
+ if ( ioctlDebug )
+ fprintf(stderr, "pioctl logon user: [%s]\r\n",szUser);
+
+ sprintf(szPath, "\\\\%s", szClient);
+ memset (&nr, 0x00, sizeof(NETRESOURCE));
+ nr.dwType=RESOURCETYPE_DISK;
+ nr.lpLocalName=0;
+ nr.lpRemoteName=szPath;
+ res = WNetAddConnection2(&nr,NULL,szUser,0);
+ if (res) {
+ if ( ioctlDebug ) {
+ fprintf(stderr, "pioctl WNetAddConnection2(%s,%s) failed: 0x%X\r\n",
+ szPath,szUser,res);
+ }
+
+ sprintf(szPath, "\\\\%s\\all", szClient);
+ res = WNetAddConnection2(&nr,NULL,szUser,0);
+ if (res) {
+ if ( ioctlDebug ) {
+ fprintf(stderr, "pioctl WNetAddConnection2(%s,%s) failed: 0x%X\r\n",
+ szPath,szUser,res);
+ }
+ goto next_attempt;
+ }
+ }
+
+ fh = CreateFile(tbuffer, GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
+ FILE_FLAG_WRITE_THROUGH, NULL);
+ fflush(stdout);
+ if (fh == INVALID_HANDLE_VALUE) {
+ gle = GetLastError();
+ if (gle && ioctlDebug ) {
+ char buf[4096];
+
+ if ( FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL,
+ gle,
+ MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),
+ buf,
+ 4096,
+ (va_list *) NULL
+ ) )
+ {
+ fprintf(stderr,"pioctl CreateFile(%s) failed: 0x%8X\r\n\t[%s]\r\n",
+ tbuffer,gle,buf);
+ }
+ }
+ }
+ }
+ }
+
+ next_attempt:
+ if ( fh == INVALID_HANDLE_VALUE ) {
+ if (GetUserNameEx(NameSamCompatible, szUser, &dwSize)) {
+ if ( ioctlDebug )
+ fprintf(stderr, "pioctl logon user: [%s]\r\n",szUser);
+
+ sprintf(szPath, "\\\\%s", szClient);
+ memset (&nr, 0x00, sizeof(NETRESOURCE));
+ nr.dwType=RESOURCETYPE_DISK;
+ nr.lpLocalName=0;
+ nr.lpRemoteName=szPath;
+ res = WNetAddConnection2(&nr,NULL,szUser,0);
+ if (res) {
+ if ( ioctlDebug ) {
+ fprintf(stderr, "pioctl WNetAddConnection2(%s,%s) failed: 0x%X\r\n",
+ szPath,szUser,res);
+ }
+
+ sprintf(szPath, "\\\\%s\\all", szClient);
+ res = WNetAddConnection2(&nr,NULL,szUser,0);
+ if (res) {
+ if ( ioctlDebug ) {
+ fprintf(stderr, "pioctl WNetAddConnection2(%s,%s) failed: 0x%X\r\n",
+ szPath,szUser,res);
+ }
+ return -1;
+ }
+ }
+
+ fh = CreateFile(tbuffer, GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
+ FILE_FLAG_WRITE_THROUGH, NULL);
+ fflush(stdout);
+ if (fh == INVALID_HANDLE_VALUE) {
+ gle = GetLastError();
+ if (gle && ioctlDebug ) {
+ char buf[4096];
+
+ if ( FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL,
+ gle,
+ MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),
+ buf,
+ 4096,
+ (va_list *) NULL
+ ) )
+ {
+ fprintf(stderr,"pioctl CreateFile(%s) failed: 0x%8X\r\n\t[%s]\r\n",
+ tbuffer,gle,buf);
+ }
+ }
+ return -1;
+ }
+ }
+ }
/* return fh and success code */
*handlep = fh;
{
long rcount;
long ioCount;
+ DWORD gle;
rcount = reqp->mp - reqp->data;
- if (rcount <= 0)
+ if (rcount <= 0) {
+ if ( IoctlDebug() )
+ fprintf(stderr, "pioctl Transceive rcount <= 0: %d\r\n",rcount);
return EINVAL; /* not supposed to happen */
+ }
if (!WriteFile(handle, reqp->data, rcount, &ioCount, NULL)) {
/* failed to write */
- return GetLastError();
+ gle = GetLastError();
+
+ if ( IoctlDebug() )
+ fprintf(stderr, "pioctl Transceive WriteFile failed: 0x%X\r\n",gle);
+ return gle;
}
if (!ReadFile(handle, reqp->data, sizeof(reqp->data), &ioCount, NULL)) {
/* failed to read */
- return GetLastError();
+ gle = GetLastError();
+
+ if ( IoctlDebug() )
+ fprintf(stderr, "pioctl Transceive ReadFile failed: 0x%X\r\n",gle);
+ return gle;
}
reqp->nbytes = ioCount; /* set # of bytes available */
{
/* not enough data left */
if (reqp->nbytes < 4) {
+ if ( IoctlDebug() )
+ fprintf(stderr, "pioctl UnmarshallLong reqp->nbytes < 4: %d\r\n",
+ reqp->nbytes);
return -1;
}
count = 1;
/* watch for buffer overflow */
- if ((reqp->mp - reqp->data) + count > sizeof(reqp->data))
+ if ((reqp->mp - reqp->data) + count > sizeof(reqp->data)) {
+ if ( IoctlDebug() )
+ fprintf(stderr, "pioctl MarshallString buffer overflow\r\n");
return -1;
+ }
if (stringp)
memcpy(reqp->mp, stringp, count);
newPath[2] = 0;
if (!SetCurrentDirectory(newPath)) {
code = GetLastError();
+
+ if ( IoctlDebug() )
+ fprintf(stderr, "pioctl fs_GetFullPath SetCurrentDirectory(%s) failed: 0x%X\r\n",
+ newPath, code);
return code;
}
}
/* now get the absolute path to the current wdir in this drive */
GetCurrentDirectory(sizeof(tpath), tpath);
- if (tpath[1] == ':')
- strcpy(outPathp, tpath + 2); /* skip drive letter */
- else if ( tpath[0] == '\\' && tpath[1] == '\\') {
+ if (tpath[1] == ':')
+ strcpy(outPathp, tpath + 2); /* skip drive letter */
+ else if ( tpath[0] == '\\' && tpath[1] == '\\') {
/* UNC path - strip off the server and sharename */
int i, count;
for ( i=2,count=2; count < 4 && tpath[i]; i++ ) {
/* if there is a non-null name after the drive, append it */
if (*firstp != 0) {
- int len = strlen(outPathp);
- if (outPathp[len-1] != '\\' && outPathp[len-1] != '/')
- strcat(outPathp, "\\");
- strcat(outPathp, firstp);
+ int len = strlen(outPathp);
+ if (outPathp[len-1] != '\\' && outPathp[len-1] != '/')
+ strcat(outPathp, "\\");
+ strcat(outPathp, firstp);
}
/* finally, if necessary, switch back to our home drive letter */
}
/* now unmarshall the return value */
- UnmarshallLong(&preq, &temp);
+ if (UnmarshallLong(&preq, &temp) != 0) {
+ CloseHandle(reqHandle);
+ return -1;
+ }
+
if (temp != 0) {
CloseHandle(reqHandle);
errno = CMtoUNIXerror(temp);
+ if ( IoctlDebug() )
+ fprintf(stderr, "pioctl temp != 0: 0x%X\r\n",temp);
return -1;
}