windows-pioctl-debugging-20080705
[openafs.git] / src / sys / pioctl_nt.c
index 009d874..53f893a 100644 (file)
@@ -29,6 +29,7 @@ RCSID
 #include <osi.h>
 
 #include <cm.h>
+#include <cm_nls.h>
 #include <cm_server.h>
 #include <cm_cell.h>
 #include <cm_user.h>
@@ -49,6 +50,9 @@ RCSID
 
 static char AFSConfigKeyName[] = AFSREG_CLT_SVC_PARAM_SUBKEY;
 
+static const char utf8_prefix[] = UTF8_PREFIX;
+static const int  utf8_prefix_size = sizeof(utf8_prefix) -  sizeof(char);
+
 #define FS_IOCTLREQUEST_MAXSIZE        8192
 /* big structure for representing and storing an IOCTL request */
 typedef struct fs_ioctlRequest {
@@ -411,6 +415,7 @@ GetIoctlHandle(char *fileNamep, HANDLE * handlep)
     DWORD ioctlDebug = IoctlDebug();
     DWORD gle;
     DWORD dwSize = sizeof(szUser);
+    int saveerrno;
 
     memset(HostName, '\0', sizeof(HostName));
     gethostname(HostName, sizeof(HostName));
@@ -488,7 +493,8 @@ GetIoctlHandle(char *fileNamep, HANDLE * handlep)
         gle = GetLastError();
         if (gle && ioctlDebug ) {
             char buf[4096];
-
+            
+            saveerrno = errno;
             if ( FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
                                NULL,
                                gle,
@@ -501,6 +507,7 @@ GetIoctlHandle(char *fileNamep, HANDLE * handlep)
                 fprintf(stderr,"pioctl CreateFile(%s) failed: 0x%X\r\n\t[%s]\r\n",
                         tbuffer,gle,buf);
             }
+            errno = saveerrno;
         }
 
         lana_GetNetbiosName(szClient, LANA_NETBIOS_NAME_FULL);
@@ -514,9 +521,11 @@ GetIoctlHandle(char *fileNamep, HANDLE * handlep)
         }
 
         if ( szUser[0] ) {
-            if ( ioctlDebug )
+            if ( ioctlDebug ) {
+                saveerrno = errno;
                 fprintf(stderr, "pioctl Explorer logon user: [%s]\r\n",szUser);
-
+                errno = saveerrno;
+            }
             sprintf(szPath, "\\\\%s", szClient);
             memset (&nr, 0x00, sizeof(NETRESOURCE));
             nr.dwType=RESOURCETYPE_DISK;
@@ -525,8 +534,10 @@ GetIoctlHandle(char *fileNamep, HANDLE * handlep)
             res = WNetAddConnection2(&nr,NULL,szUser,0);
             if (res) {
                 if ( ioctlDebug ) {
+                    saveerrno = errno;
                     fprintf(stderr, "pioctl WNetAddConnection2(%s,%s) failed: 0x%X\r\n",
                              szPath,szUser,res);
+                    errno = saveerrno;
                 }
                 gonext = 1;
             }
@@ -535,8 +546,10 @@ GetIoctlHandle(char *fileNamep, HANDLE * handlep)
             res = WNetAddConnection2(&nr,NULL,szUser,0);
             if (res) {
                 if ( ioctlDebug ) {
+                    saveerrno = errno;
                     fprintf(stderr, "pioctl WNetAddConnection2(%s,%s) failed: 0x%X\r\n",
                              szPath,szUser,res);
+                    errno = saveerrno;
                 }
                 gonext = 1;
             }
@@ -553,6 +566,7 @@ GetIoctlHandle(char *fileNamep, HANDLE * handlep)
                 if (gle && ioctlDebug ) {
                     char buf[4096];
 
+                    saveerrno = errno;
                     if ( FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
                                         NULL,
                                         gle,
@@ -565,6 +579,7 @@ GetIoctlHandle(char *fileNamep, HANDLE * handlep)
                         fprintf(stderr,"pioctl CreateFile(%s) failed: 0x%X\r\n\t[%s]\r\n",
                                  tbuffer,gle,buf);
                     }
+                    errno = saveerrno;
                 }
             }
         }
@@ -576,9 +591,11 @@ GetIoctlHandle(char *fileNamep, HANDLE * handlep)
 
         dwSize = sizeof(szUser);
         if (GetLSAPrincipalName(szUser, &dwSize)) {
-            if ( ioctlDebug )
+            if ( ioctlDebug ) {
+                saveerrno = errno;
                 fprintf(stderr, "pioctl LSA Principal logon user: [%s]\r\n",szUser);
-
+                errno = saveerrno;
+            }
             sprintf(szPath, "\\\\%s", szClient);
             memset (&nr, 0x00, sizeof(NETRESOURCE));
             nr.dwType=RESOURCETYPE_DISK;
@@ -587,8 +604,10 @@ GetIoctlHandle(char *fileNamep, HANDLE * handlep)
             res = WNetAddConnection2(&nr,NULL,szUser,0);
             if (res) {
                 if ( ioctlDebug ) {
+                    saveerrno = errno;
                     fprintf(stderr, "pioctl WNetAddConnection2(%s,%s) failed: 0x%X\r\n",
                              szPath,szUser,res);
+                    errno = saveerrno;
                 }
                 gonext = 1;
             }
@@ -597,8 +616,10 @@ GetIoctlHandle(char *fileNamep, HANDLE * handlep)
             res = WNetAddConnection2(&nr,NULL,szUser,0);
             if (res) {
                 if ( ioctlDebug ) {
+                    saveerrno = errno;
                     fprintf(stderr, "pioctl WNetAddConnection2(%s,%s) failed: 0x%X\r\n",
                              szPath,szUser,res);
+                    errno = saveerrno;
                 }
                 gonext = 1;
             }
@@ -615,6 +636,7 @@ GetIoctlHandle(char *fileNamep, HANDLE * handlep)
                 if (gle && ioctlDebug ) {
                     char buf[4096];
 
+                    saveerrno = errno;
                     if ( FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
                                         NULL,
                                         gle,
@@ -627,6 +649,8 @@ GetIoctlHandle(char *fileNamep, HANDLE * handlep)
                         fprintf(stderr,"pioctl CreateFile(%s) failed: 0x%X\r\n\t[%s]\r\n",
                                  tbuffer,gle,buf);
                     }
+                    errno = saveerrno;
+
                 }
             }
         }
@@ -636,9 +660,11 @@ GetIoctlHandle(char *fileNamep, HANDLE * handlep)
     if ( fh == INVALID_HANDLE_VALUE ) {
         dwSize = sizeof(szUser);
         if (GetUserNameEx(NameSamCompatible, szUser, &dwSize)) {
-            if ( ioctlDebug )
+            if ( ioctlDebug ) {
+                saveerrno = errno;
                 fprintf(stderr, "pioctl SamCompatible logon user: [%s]\r\n",szUser);
-
+                errno = saveerrno;
+            }
             sprintf(szPath, "\\\\%s", szClient);
             memset (&nr, 0x00, sizeof(NETRESOURCE));
             nr.dwType=RESOURCETYPE_DISK;
@@ -647,8 +673,10 @@ GetIoctlHandle(char *fileNamep, HANDLE * handlep)
             res = WNetAddConnection2(&nr,NULL,szUser,0);
             if (res) {
                 if ( ioctlDebug ) {
+                    saveerrno = errno;
                     fprintf(stderr, "pioctl WNetAddConnection2(%s,%s) failed: 0x%X\r\n",
                              szPath,szUser,res);
+                    errno = saveerrno;
                 }
             }
 
@@ -656,8 +684,10 @@ GetIoctlHandle(char *fileNamep, HANDLE * handlep)
             res = WNetAddConnection2(&nr,NULL,szUser,0);
             if (res) {
                 if ( ioctlDebug ) {
+                    saveerrno = errno;
                     fprintf(stderr, "pioctl WNetAddConnection2(%s,%s) failed: 0x%X\r\n",
                              szPath,szUser,res);
+                    errno = saveerrno;
                 }
                 return -1;
             }
@@ -671,6 +701,7 @@ GetIoctlHandle(char *fileNamep, HANDLE * handlep)
                 if (gle && ioctlDebug ) {
                     char buf[4096];
 
+                    saveerrno = errno;
                     if ( FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
                                         NULL,
                                         gle,
@@ -683,6 +714,7 @@ GetIoctlHandle(char *fileNamep, HANDLE * handlep)
                         fprintf(stderr,"pioctl CreateFile(%s) failed: 0x%X\r\n\t[%s]\r\n",
                                  tbuffer,gle,buf);
                     }
+                    errno = saveerrno;
                 }
                 return -1;
             }
@@ -703,11 +735,16 @@ Transceive(HANDLE handle, fs_ioctlRequest_t * reqp)
     long rcount;
     long ioCount;
     DWORD gle;
+    DWORD ioctlDebug = IoctlDebug();
+    int save;
 
     rcount = (long)(reqp->mp - reqp->data);
     if (rcount <= 0) {
-        if ( IoctlDebug() )
+        if ( ioctlDebug ) {
+            save = errno;
             fprintf(stderr, "pioctl Transceive rcount <= 0: %d\r\n",rcount);
+            errno = save;
+        }
        return EINVAL;          /* not supposed to happen */
     }
 
@@ -715,8 +752,11 @@ Transceive(HANDLE handle, fs_ioctlRequest_t * reqp)
        /* failed to write */
        gle = GetLastError();
 
-        if ( IoctlDebug() )
+        if ( ioctlDebug ) {
+            save = errno;
             fprintf(stderr, "pioctl Transceive WriteFile failed: 0x%X\r\n",gle);
+            errno = save;
+        }
         return gle;
     }
 
@@ -724,8 +764,11 @@ Transceive(HANDLE handle, fs_ioctlRequest_t * reqp)
        /* failed to read */
        gle = GetLastError();
 
-        if ( IoctlDebug() )
+        if ( ioctlDebug ) {
+            save = errno;
             fprintf(stderr, "pioctl Transceive ReadFile failed: 0x%X\r\n",gle);
+            errno = save;
+        }
         return gle;
     }
 
@@ -747,11 +790,16 @@ MarshallLong(fs_ioctlRequest_t * reqp, long val)
 static long
 UnmarshallLong(fs_ioctlRequest_t * reqp, long *valp)
 {
+    int save;
+
     /* not enough data left */
     if (reqp->nbytes < 4) {
-        if ( IoctlDebug() )
+        if ( IoctlDebug() ) {
+            save = errno;
             fprintf(stderr, "pioctl UnmarshallLong reqp->nbytes < 4: %d\r\n",
                      reqp->nbytes);
+            errno = save;
+        }
        return -1;
     }
 
@@ -763,22 +811,36 @@ UnmarshallLong(fs_ioctlRequest_t * reqp, long *valp)
 
 /* includes marshalling NULL pointer as a null (0 length) string */
 static long
-MarshallString(fs_ioctlRequest_t * reqp, char *stringp)
+MarshallString(fs_ioctlRequest_t * reqp, char *stringp, int is_utf8)
 {
     int count;
+    int save;
 
     if (stringp)
        count = (int)strlen(stringp) + 1;/* space required including null */
     else
        count = 1;
 
+    if (is_utf8) {
+        count += utf8_prefix_size;
+    }
+
     /* watch for buffer overflow */
     if ((reqp->mp - reqp->data) + count > sizeof(reqp->data)) {
-        if ( IoctlDebug() )
+        if ( IoctlDebug() ) {
+            save = errno;
             fprintf(stderr, "pioctl MarshallString buffer overflow\r\n");
+            errno = save;
+        }
        return -1;
     }
 
+    if (is_utf8) {
+        memcpy(reqp->mp, utf8_prefix, utf8_prefix_size);
+        reqp->mp += utf8_prefix_size;
+        count -= utf8_prefix_size;
+    }
+
     if (stringp)
        memcpy(reqp->mp, stringp, count);
     else
@@ -802,6 +864,7 @@ fs_GetFullPath(char *pathp, char *outPathp, long outSize)
     int doSwitch;
     char newPath[3];
     char * p;
+    int save;
 
     if (pathp[0] != 0 && pathp[1] == ':') {
        /* there's a drive letter there */
@@ -856,9 +919,12 @@ fs_GetFullPath(char *pathp, char *outPathp, long outSize)
        if (!SetCurrentDirectory(newPath)) {
            code = GetLastError();
 
-            if ( IoctlDebug() )
+            if ( IoctlDebug() ) {
+                save = errno;
                 fprintf(stderr, "pioctl fs_GetFullPath SetCurrentDirectory(%s) failed: 0x%X\r\n",
                          newPath, code);
+                errno = save;
+            }
            return code;
        }
     }
@@ -906,14 +972,15 @@ fs_GetFullPath(char *pathp, char *outPathp, long outSize)
     return 0;
 }
 
-long
-pioctl(char *pathp, long opcode, struct ViceIoctl *blobp, int follow)
+static long
+pioctl_int(char *pathp, long opcode, struct ViceIoctl *blobp, int follow, int is_utf8)
 {
     fs_ioctlRequest_t preq;
     long code;
     long temp;
     char fullPath[1000];
     HANDLE reqHandle;
+    int save;
 
     code = GetIoctlHandle(pathp, &reqHandle);
     if (code) {
@@ -945,7 +1012,7 @@ pioctl(char *pathp, long opcode, struct ViceIoctl *blobp, int follow)
        strcpy(fullPath, "");
     }
 
-    MarshallString(&preq, fullPath);
+    MarshallString(&preq, fullPath, is_utf8);
     if (blobp->in_size) {
         if (blobp->in_size > sizeof(preq.data) - (preq.mp - preq.data)*sizeof(char)) {
             errno = E2BIG;
@@ -971,8 +1038,11 @@ pioctl(char *pathp, long opcode, struct ViceIoctl *blobp, int follow)
     if (temp != 0) {
        CloseHandle(reqHandle);
        errno = CMtoUNIXerror(temp);
-        if ( IoctlDebug() )
+        if ( IoctlDebug() ) {
+            save = errno;
             fprintf(stderr, "pioctl temp != 0: 0x%X\r\n",temp);
+            errno = save;
+        }
        return -1;
     }
 
@@ -989,3 +1059,16 @@ pioctl(char *pathp, long opcode, struct ViceIoctl *blobp, int follow)
     CloseHandle(reqHandle);
     return 0;
 }
+
+long
+pioctl_utf8(char * pathp, long opcode, struct ViceIoctl * blobp, int follow)
+{
+    return pioctl_int(pathp, opcode, blobp, follow, TRUE);
+}
+
+long
+pioctl(char * pathp, long opcode, struct ViceIoctl * blobp, int follow)
+{
+    return pioctl_int(pathp, opcode, blobp, follow, FALSE);
+}
+