#include <string.h>
#include <winioctl.h>
#include <winsock2.h>
+#define SECURITY_WIN32
+#include <security.h>
#include <nb30.h>
#include <osi.h>
#include <smb.h>
#include <pioctl_nt.h>
-/* Are we using the canonical Netbios name (AFS)? */
-BOOL smb_TruncateNetbios = FALSE; /* what the registry says */
-BOOL smb_TruncateNetbiosReal = FALSE; /* what we actually grant */
+#include <lanahelper.h>
static char AFSConfigKeyName[] =
"SYSTEM\\CurrentControlSet\\Services\\TransarcAFSDaemon\\Parameters";
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 *drivep;
- char hostName[256];
- char tbuffer[100];
- char buf[200];
- char explicitNetbiosName[32];
- DWORD isGateway = 0;
- char *ctemp;
+ char netbiosName[MAX_NB_NAME_LENGTH];
+ char tbuffer[256]="";
HANDLE fh;
- HKEY parmKey;
- DWORD dummyLen;
- long code;
+ 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, ':');
tbuffer[0] = *(drivep - 1);
tbuffer[1] = ':';
strcpy(tbuffer + 2, SMB_IOCTL_FILENAME);
- } else
- strcpy(tbuffer, SMB_IOCTL_FILENAME);
- } else {
- /* No file name specified, use UNC name */
- code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSConfigKeyName, 0,
- KEY_QUERY_VALUE, &parmKey);
- if (code != ERROR_SUCCESS)
- goto nogateway;
-
- dummyLen = sizeof(buf);
- code = RegQueryValueEx(parmKey, "TruncateNetbios", NULL, NULL,
- (BYTE *) buf, &dummyLen);
- if (code == ERROR_SUCCESS)
+ } else if (fileNamep[0] == fileNamep[1] &&
+ fileNamep[0] == '\\')
{
- if (!stricmp( (const char *) buf, "on"))
+ int count = 0, i = 0;
+
+ while (count < 4 && fileNamep[i]) {
+ tbuffer[i] = fileNamep[i];
+ if ( tbuffer[i++] == '\\' )
+ count++;
+ }
+ if (fileNamep[i] == 0)
+ tbuffer[i++] = '\\';
+ tbuffer[i] = 0;
+ strcat(tbuffer, SMB_IOCTL_FILENAME);
+ } else {
+ char curdir[256]="";
+
+ GetCurrentDirectory(sizeof(curdir), curdir);
+ if ( curdir[1] == ':' ) {
+ tbuffer[0] = curdir[0];
+ tbuffer[1] = ':';
+ strcpy(tbuffer + 2, SMB_IOCTL_FILENAME);
+ } else if (curdir[0] == curdir[1] &&
+ curdir[0] == '\\')
{
- smb_TruncateNetbios = TRUE;
- smb_TruncateNetbiosReal = TRUE;
+ int count = 0, i = 0;
+
+ while (count < 4 && curdir[i]) {
+ tbuffer[i] = curdir[i];
+ if ( tbuffer[i++] == '\\' )
+ count++;
+ }
+ if (tbuffer[i] == 0)
+ tbuffer[i++] = '\\';
+ tbuffer[i] = 0;
+ strcat(tbuffer, SMB_IOCTL_FILENAME_NOSLASH);
}
}
+ }
+ 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);
+ }
- dummyLen = sizeof(isGateway);
- code = RegQueryValueEx(parmKey, "IsGateway", NULL, NULL,
- (BYTE *) &isGateway, &dummyLen);
-
- /* Is there an explicit name we should use? */
- dummyLen = sizeof(explicitNetbiosName);
- code = RegQueryValueEx(parmKey, "NetbiosName", NULL, NULL,
- (BYTE *) &explicitNetbiosName, &dummyLen);
- if (!code == ERROR_SUCCESS)
- {
- explicitNetbiosName[0] = 0;
+ fflush(stdout);
+ /* now open the file */
+ 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);
+ }
}
+#ifdef COMMENT
+ if (gle != ERROR_DOWNGRADE_DETECTED)
+ return -1;
+#endif
+
+ lana_GetNetbiosName(szClient, LANA_NETBIOS_NAME_FULL);
- /* Look for gateway host in Registry */
- dummyLen = sizeof(hostName);
- code = RegQueryValueEx(parmKey, "Gateway", NULL, NULL, hostName,
- &dummyLen);
- RegCloseKey(parmKey);
- if (code == ERROR_SUCCESS)
- goto havehost;
-
- nogateway:
- /* No gateway name in registry; use ourself */
-#ifndef AFS_WIN95_ENV
- gethostname(hostName, sizeof(hostName));
-#else
+ if (RegOpenKey (HKEY_CURRENT_USER,
+ TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer"), &hk) == 0)
{
- int hostsize;
- /* DJGPP version of gethostname gets the NetBIOS
- * name of the machine, so that is what we are using for
- * the AFS server name instead of the DNS name. */
- hostsize = sizeof(hostName);
- GetComputerName(hostName, &hostsize);
+ DWORD dwType = REG_SZ;
+ RegQueryValueEx (hk, TEXT("Logon User Name"), NULL, &dwType, (PBYTE)szUser, &dwSize);
+ RegCloseKey (hk);
}
-#endif /* AFS_WIN95_ENV */
- havehost:
- ctemp = strchr(hostName, '.'); /* turn ntafs.* into ntafs */
- if (ctemp)
- *ctemp = 0;
- hostName[11] = 0;
+ 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;
+ }
+ }
- if (explicitNetbiosName[0])
- {
- _strupr(explicitNetbiosName);
- sprintf(tbuffer, "\\\\%s\\all%s",
- explicitNetbiosName, SMB_IOCTL_FILENAME);
- }
- else if (smb_TruncateNetbiosReal) {
- sprintf(tbuffer, "\\\\AFS\\all%s", SMB_IOCTL_FILENAME);
- }
- else
- {
- _strupr(hostName);
- sprintf(tbuffer, "\\\\%s-AFS\\all%s",
- hostName, SMB_IOCTL_FILENAME);
+ 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);
+ }
+ }
+ }
}
}
- fflush(stdout);
- /* now open the file */
- 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;
+ 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);
pathHasDrive = 0;
}
- if (*firstp == '\\' || *firstp == '/') {
- /* already an absolute pathname, just copy it back */
- strcpy(outPathp, firstp);
- return 0;
+ if ( firstp[0] == '\\' && firstp[1] == '\\') {
+ /* UNC path - strip off the server and sharename */
+ int i, count;
+ for ( i=2,count=2; count < 4 && firstp[i]; i++ ) {
+ if ( firstp[i] == '\\' || firstp[i] == '/' ) {
+ count++;
+ }
+ }
+ if ( firstp[i] == 0 ) {
+ strcpy(outPathp,"\\");
+ } else {
+ strcpy(outPathp,&firstp[--i]);
+ }
+ return 0;
+ } else if (firstp[0] == '\\' || firstp[0] == '/') {
+ /* already an absolute pathname, just copy it back */
+ strcpy(outPathp, firstp);
+ return 0;
}
GetCurrentDirectory(sizeof(origPath), origPath);
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);
- strcpy(outPathp, tpath + 2); /* skip drive letter */
+ 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 ( tpath[i] == '\\' || tpath[i] == '/' ) {
+ count++;
+ }
+ }
+ if ( tpath[i] == 0 ) {
+ strcpy(outPathp,"\\");
+ } else {
+ strcpy(outPathp,&tpath[--i]);
+ }
+ } else {
+ /* this should never happen */
+ strcpy(outPathp, tpath);
+ }
+
/* if there is a non-null name after the drive, append it */
if (*firstp != 0) {
- 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;
}