windows-tests-torture-enforce-querypath-info-errors-20090201
[openafs.git] / src / WINNT / tests / torture / Source / nbio.c
index f4140d6..74760a1 100644 (file)
@@ -21,6 +21,7 @@
 
 #include "includes.h"
 #include "common.h"
+#include <stdlib.h>
 
 extern int verbose;
 
@@ -32,6 +33,7 @@ __declspec( thread ) extern int     AfsTrace;
 __declspec( thread ) extern int     *pThreadStatus;
 __declspec( thread ) extern int     LogID;
 __declspec( thread ) extern char    *IoBuffer;
+__declspec( thread ) extern int     BufferSize;
 __declspec( thread ) extern char    AfsLocker[256];
 __declspec( thread ) extern char    OriginalAfsLocker[256];
 __declspec( thread ) extern char    HostName[256];
@@ -40,15 +42,17 @@ __declspec( thread ) extern FTABLE  ftable[MAX_FILES];
 __declspec( thread ) extern struct  cmd_struct ThreadCommandInfo[CMD_MAX_CMD + 1];
 __declspec( thread ) extern EXIT_STATUS *pExitStatus;
 __declspec( thread ) extern DWORD   LastKnownError;
+__declspec( thread ) int EnforcePathInfoErrors = 0;
+
 extern void LogMessage(int ProcessNumber, char *HostName, char *FileName, char *message, int LogID);
 
-int  CreateObject(const char *fname, uint32 DesiredAccess,
+HANDLE CreateObject(const char *fname, uint32 DesiredAccess,
                   uint32 FileAttributes, uint32 ShareAccess,
                   uint32 CreateDisposition, uint32 CreateOptions);
 void DumpAFSLog(char * HostName, int LogID);
 int  FindHandle(int handle);
 int  GetFileList(char *Mask, void (*fn)(file_info *, const char *, void *), void *state);
-BOOL GetFileInfo(char *FileName, int fnum, uint16 *mode, size_t *size,
+BOOL GetFileInfo(char *FileName, HANDLE fd, uint16 *mode, size_t *size,
                        time_t *c_time, time_t *a_time, time_t *m_time, 
                        time_t *w_time);
 BOOL GetPathInfo(const char *fname, time_t *c_time, time_t *a_time, time_t *m_time, 
@@ -59,7 +63,7 @@ void EndFirstTimer(int cmd, int Type);
 void StartSecondTime(int cmd);
 void EndSecondTime(int cmd);
 void SubstituteString(char *s,const char *pattern,const char *insert, size_t len);
-int  SystemCall(char *command);
+intptr_t  SystemCall(char *command);
 HANDLE WinFindFirstFile(char *Mask, void **FileData, char *cFileName, int *dwFileAttributes);
 int  WinFindNextFile(HANDLE hFind, void **FileData, char *cFileName, int *dwFileAttributes);
 
@@ -94,7 +98,7 @@ int nb_unlink(char *fname)
     if (!rc)
     {
         LeaveThread(0, "", CMD_UNLINK);
-        sprintf(temp, "FILE: DeleteFile %s failed\n", fname);
+        sprintf(temp, "FILE: DeleteFile %s failed GLE(0x%x)\n", fname, GetLastError());
         if (verbose)
             printf("%s", temp);
         LogMessage(ProcessNumber, HostName, FileName, temp, LogID);
@@ -127,7 +131,7 @@ int nb_Xrmdir(char *Directory, char *type)
     sprintf(FileName, "Thread_%05d.log", ProcessNumber);
     if (strlen(Directory) == 0)
     {
-        return(LeaveThread(1, "rmdir failed no path found\n", CMD_XRMDIR));
+        return(LeaveThread(1, "rmdir failed no path specified\n", CMD_XRMDIR));
     }
     strcpy(NewDirectory, Directory);
     memset(command, '\0', sizeof(command));
@@ -146,7 +150,7 @@ int nb_Xrmdir(char *Directory, char *type)
         EndFirstTimer(CMD_XRMDIR, 0);
         sprintf(temp, "rmdir failed on %s\n", command);
         LeaveThread(rc, temp, CMD_XRMDIR);
-        sprintf(temp, "FAILURE: Thread %d - rmdir failed on\n    %s\n", ProcessNumber, command);
+        sprintf(temp, "FAILURE: Thread %d - Xrmdir failed on \"%s\"\n", ProcessNumber, command);
         LogMessage(ProcessNumber, HostName, FileName, temp, LogID);
         return(-1);
     }
@@ -166,7 +170,7 @@ int nb_Mkdir(char *Directory)
     sprintf(FileName, "Thread_%05d.log", ProcessNumber);
     if (strlen(Directory) == 0)
     {
-        return(LeaveThread(1, "mkdir failed on no path found\n", CMD_MKDIR));
+        return(LeaveThread(1, "mkdir failed on no path specified\n", CMD_MKDIR));
     }
     strcpy(NewDirectory, Directory);
     memset(command, '\0', sizeof(command));
@@ -181,7 +185,7 @@ int nb_Mkdir(char *Directory)
         EndFirstTimer(CMD_MKDIR, 0);
         sprintf(temp,  "mkdir failed on %s\n", command);
         LeaveThread(rc, temp, CMD_MKDIR);
-        sprintf(temp, "ERROR: Thread %d - mkdir failed on\n    %s\n", ProcessNumber, command);
+        sprintf(temp, "ERROR: Thread %d - mkdir failed on \"%s\"\n", ProcessNumber, command);
         LogMessage(ProcessNumber, HostName, FileName, temp, LogID);
         return(-1);
     }
@@ -199,7 +203,7 @@ int nb_Attach(char *Locker, char *Drive)
     sprintf(FileName, "Thread_%05d.log", ProcessNumber);
     if (strlen(Locker) == 0)
     {
-        return(LeaveThread(1, "attach failed no locker found\n", CMD_ATTACH));
+        return(LeaveThread(1, "attach failed no locker specified\n", CMD_ATTACH));
     }
     memset(command, '\0', sizeof(command));
     strcpy(command,"attach -q ");
@@ -219,7 +223,7 @@ int nb_Attach(char *Locker, char *Drive)
         EndFirstTimer(CMD_ATTACH, 0);
         sprintf(pExitStatus->Reason, "attach failed on %s\n", command);
         pExitStatus->ExitStatus = rc;
-        sprintf(temp, "ERROR: Thread %d - attach failed on\n    %s\n", ProcessNumber, command);
+        sprintf(temp, "ERROR: Thread %d - attach failed on \"%s\"\n", ProcessNumber, command);
         LogMessage(ProcessNumber, HostName, FileName, temp, LogID);
     }
     EndFirstTimer(CMD_ATTACH, 1);
@@ -259,7 +263,7 @@ int nb_Detach(char *Name, char *type)
         EndFirstTimer(CMD_DETACH, 0);
         sprintf(temp, "detach failed on %s\n", command);
         LeaveThread(rc, temp, CMD_DETACH);
-        sprintf(temp, "ERROR: Thread %d - detach failed on\n    %s\n", ProcessNumber, command);
+        sprintf(temp, "ERROR: Thread %d - detach failed on \"%s\"\n", ProcessNumber, command);
         LogMessage(ProcessNumber, HostName, FileName, temp, LogID);
         return(-1);
     }
@@ -282,7 +286,7 @@ int nb_CreateFile(char *path, DWORD size)
     sprintf(FileName, "Thread_%05d.log", ProcessNumber);
     if (strlen(path) == 0)
     {
-        return(LeaveThread(1, "nb_DeleteFile failed no path found\n", CMD_CREATEFILE));
+        return(LeaveThread(1, "nb_DeleteFile failed no path specified\n", CMD_CREATEFILE));
     }
 
     strcpy(NewPath, path);
@@ -298,10 +302,11 @@ int nb_CreateFile(char *path, DWORD size)
 
     if (fHandle == INVALID_HANDLE_VALUE)
     {
+        rc = GetLastError();
         EndFirstTimer(CMD_CREATEFILE, 0);
-        sprintf(temp, "Create file failed on %s\n", NewPath);
-        LeaveThread(0, "", CMD_CREATEFILE);
-        sprintf(temp, "ERROR: Thread %d - Create file failed on\n    %s\n", ProcessNumber, NewPath);
+        sprintf(temp, "Create file failed on \"%s\" GLE(0x%x)\n", NewPath, rc);
+        LeaveThread(0, temp, CMD_CREATEFILE);
+        sprintf(temp, "ERROR: Thread %d - Create file failed on \"%s\" GLE(0x%x)\n", ProcessNumber, NewPath, rc);
         LogMessage(ProcessNumber, HostName, FileName, temp, LogID);
         return(-1);
     }
@@ -332,7 +337,7 @@ int nb_CopyFile(char *Source, char *Destination)
     sprintf(FileName, "Thread_%05d.log", ProcessNumber);
     if ((strlen(Source) == 0) || (strlen(Destination) == 0))
     {
-        return(LeaveThread(1, "nb_CopyFile failed to copy files: either source or destination path not found\n", CMD_COPYFILES));
+        return(LeaveThread(1, "nb_CopyFile failed to copy files: either source or destination path not specified\n", CMD_COPYFILES));
     }
     strcpy(NewSource, Source);
     strcpy(NewDestination, Destination);
@@ -346,9 +351,9 @@ int nb_CopyFile(char *Source, char *Destination)
     if (rc)
     {
         EndFirstTimer(CMD_COPYFILES, 0);
-        sprintf(temp, "copy failed on %s\n", command);
+        sprintf(temp, "copy failed on \"%s\"\n", command);
         LeaveThread(rc, temp, CMD_COPYFILES);
-        sprintf(temp, "FAILURE: Thread %d - copy failed on\n    %s\n", ProcessNumber, command);
+        sprintf(temp, "FAILURE: Thread %d - copy failed on \"%s\"\n", ProcessNumber, command);
         LogMessage(ProcessNumber, HostName, FileName, temp, LogID);
         if (verbose)
             printf("%s", temp);
@@ -369,7 +374,7 @@ int nb_DeleteFile(char *path)
     sprintf(FileName, "Thread_%05d.log", ProcessNumber);
     if (strlen(path) == 0)
     {
-        return(LeaveThread(1, "nb_DeleteFile failed to delete files: no path found\n", CMD_DELETEFILES));
+        return(LeaveThread(1, "nb_DeleteFile failed to delete files: no path specified\n", CMD_DELETEFILES));
     }
     strcpy(NewPath, path);
 
@@ -382,9 +387,9 @@ int nb_DeleteFile(char *path)
     if (rc)
     {
         EndFirstTimer(CMD_DELETEFILES, 0);
-        sprintf(temp, "del failed on %s\n", NewPath);
+        sprintf(temp, "del failed on \"%s\"\n", NewPath);
         LeaveThread(rc, temp, CMD_DELETEFILES);
-        sprintf(temp, "ERROR: Thread %d - del failed on\n    %s\n", ProcessNumber, command);
+        sprintf(temp, "ERROR: Thread %d - del failed on \"%s\"\n", ProcessNumber, command);
         LogMessage(ProcessNumber, HostName, FileName, temp, LogID);
         return(-1);
     }
@@ -394,7 +399,7 @@ int nb_DeleteFile(char *path)
 
 int nb_xcopy(char *Source, char *Destination)
 {
-    DWORD   rc;
+    intptr_t   rc;
     char    FileName[128];
     char    temp[512];
     char    command[256];
@@ -417,10 +422,9 @@ int nb_xcopy(char *Source, char *Destination)
     if (rc)
     {
         EndFirstTimer(CMD_XCOPY, 0);
-//        sprintf(temp, "xcopy failed on %s\n", command);
-//        LeaveThread(rc, temp, CMD_XCOPY);
-        LeaveThread(0, "", CMD_XCOPY);
-        sprintf(temp, "FAIURE: Thread %d - xcopy failed on\n    %s\n", ProcessNumber, command);
+        sprintf(temp, "xcopy failed on %s\n", command);
+        LeaveThread((int)rc, temp, CMD_XCOPY);
+        sprintf(temp, "FAIURE: Thread %d - xcopy failed on \"%s\"\n", ProcessNumber, command);
         LogMessage(ProcessNumber, HostName, FileName, temp, LogID);
         return(-1);
     }
@@ -452,9 +456,9 @@ int nb_Move(char *Source, char *Destination)
     if (rc)
     {
         EndFirstTimer(CMD_MOVE, 0);
-        sprintf(temp, "move failed on %s\n", command);
+        sprintf(temp, "move failed on \"%s\"\n", command);
         LeaveThread(rc, temp, CMD_MOVE);
-        sprintf(temp, "FAILURE: Thread %d - move failed on\n    %s\n", ProcessNumber, command);
+        sprintf(temp, "FAILURE: Thread %d - move failed on \"%s\"\n", ProcessNumber, command);
         LogMessage(ProcessNumber, HostName, FileName, temp, LogID);
         return(-1);
     }
@@ -464,7 +468,7 @@ int nb_Move(char *Source, char *Destination)
 
 int nb_createx(char *fname, unsigned create_options, unsigned create_disposition, int handle)
 {
-    int     fd;
+    HANDLE  fd;
     int     i;
     uint32  desired_access;
     char    FileName[128];
@@ -486,32 +490,23 @@ int nb_createx(char *fname, unsigned create_options, unsigned create_disposition
 
     StartFirstTimer();
     fd = CreateObject(path, 
-                        desired_access,
-                        0x0,
-                        FILE_SHARE_READ|FILE_SHARE_WRITE, 
-                        create_disposition, 
-                        create_options);
+                       desired_access,
+                       0x0,
+                       FILE_SHARE_READ|FILE_SHARE_WRITE, 
+                       create_disposition, 
+                       create_options);
 
-    if (fd == -1 && handle != -1)
+    if (fd == INVALID_HANDLE_VALUE && handle != -1)
     {
         if (create_options & FILE_DIRECTORY_FILE)
         {
-            int rc;
-
-            rc = GetLastError();
-        if ((rc != ERROR_FILE_NOT_FOUND) && (rc != ERROR_PATH_NOT_FOUND))
-            if (rc != ERROR_ALREADY_EXISTS)
-            {
-                EndFirstTimer(CMD_NTCREATEX, 0);
-                SetLastError(rc);
-                LeaveThread(0, "", CMD_NTCREATEX);
-                sprintf(temp, "Directory: unable to create directory %s\n", path);
-                if (verbose)
-                    printf("%s", temp);
-                LogMessage(ProcessNumber, HostName, FileName, temp, LogID);
-                return(-1);
-            }
-            fd = 0;
+            EndFirstTimer(CMD_NTCREATEX, 0);
+            LeaveThread(0, "", CMD_NTCREATEX);
+            sprintf(temp, "Directory: unable to create directory %s\n", path);
+            if (verbose)
+                printf("%s", temp);
+            LogMessage(ProcessNumber, HostName, FileName, temp, LogID);
+            return(-1);
         }
         else
         {
@@ -527,18 +522,14 @@ int nb_createx(char *fname, unsigned create_options, unsigned create_disposition
 
     EndFirstTimer(CMD_NTCREATEX, 1);
 
-    if (create_options & FILE_DIRECTORY_FILE)
-        fd = 0;
-
-    if (fd != -1 && handle == -1)
+    if (fd != INVALID_HANDLE_VALUE && handle == -1)
     {
-        if (fd > 1)
-            CloseHandle((HANDLE)fd);
+        CloseHandle(fd);
         nb_unlink(fname);
         return(0);
     }
 
-    if (fd == -1 && handle == -1)
+    if (fd == INVALID_HANDLE_VALUE && handle == -1)
         return(0);
 
     for (i = 0; i < MAX_FILES; i++) 
@@ -563,20 +554,23 @@ int nb_createx(char *fname, unsigned create_options, unsigned create_disposition
 int nb_writex(int handle, int offset, int size, int ret_size)
 {
     int     i;
-    int     status;
+    ssize_t status;
     char    FileName[128];
     char    temp[512];
+    unsigned char magic = (unsigned char)getpid();
 
     sprintf(FileName, "Thread_%05d.log", ProcessNumber);
 
-    if (IoBuffer[0] == 0) 
-        memset(IoBuffer, 1, sizeof(IoBuffer));
+    if (IoBuffer[0] != magic ||
+        IoBuffer[1] != magic ||
+        IoBuffer[2] != magic ||
+        IoBuffer[3] != magic)
+        memset(IoBuffer, magic, BufferSize);
 
     if ((i = FindHandle(handle)) == -1)
         return(-1);
     StartFirstTimer();
     status = nb_write(ftable[i].fd, IoBuffer, offset, size);
-
     if (status != ret_size) 
     {
         EndFirstTimer(CMD_WRITEX, 0);
@@ -640,7 +634,7 @@ int nb_lock(int handle, int offset, int size, int timeout, unsigned char locktyp
 int nb_readx(int handle, int offset, int size, int ret_size)
 {
     int     i;
-    int     ret;
+    ssize_t ret;
     char    FileName[128];
     char    temp[512];
 
@@ -657,10 +651,10 @@ int nb_readx(int handle, int offset, int size, int ret_size)
         EndFirstTimer(CMD_READX, 0);
         LeaveThread(0, "", CMD_READX);
         if (ret == 0)
-            sprintf(temp, "File: read failed on index=%d, offset=%d ReadSize=%d ActualRead=%d handle=%d\n",
-                    handle, offset, size, ret, ftable[i].fd);
+            sprintf(temp, "File: read failed on index=%d, offset=%d ReadSize=%d ActualRead=%d handle=%p GLE(0x%x)\n",
+                    handle, offset, size, ret, ftable[i].fd, GetLastError());
         if (ret == -1)
-            sprintf(temp, "File: %s. On read, cannot set file pointer\n", ftable[i].name);
+            sprintf(temp, "File: %s. On read, cannot set file pointer GLE(0x%x)\n", ftable[i].name, GetLastError());
         if (verbose)
             printf("%s", temp);
         nb_close(handle);
@@ -724,7 +718,7 @@ int nb_rmdir(char *fname)
     if (!rc)
     {
         LeaveThread(0, "", CMD_RMDIR);
-        sprintf(temp, "Directory: RemoveDirectory %s failed\n", fname);
+        sprintf(temp, "Directory: RemoveDirectory %s failed GLE(0x%x)\n", fname, GetLastError());
         if (verbose)
             printf("%s", temp);
         LogMessage(ProcessNumber, HostName, FileName, temp, LogID);
@@ -755,7 +749,7 @@ int nb_rename(char *old, char *New)
     if (!rc)
     {
         LeaveThread(0, "", CMD_RENAME);
-        sprintf(temp, "File: rename %s %s failed\n", old, New);
+        sprintf(temp, "File: rename %s %s failed GLE(0x%x)\n", old, New, GetLastError());
         if (verbose)
             printf("%s", temp);
         LogMessage(ProcessNumber, HostName, FileName, temp, LogID);
@@ -764,17 +758,36 @@ int nb_rename(char *old, char *New)
     return(0);
 }
 
-
+/* 
+ * Type is used to determine whether the file is expected 
+ * to exist or not.  It is overloaded (temporarily) to control
+ * Flag which indicates whether an error is treated as an error
+ * or not.  The StreamFiles.txt script does not have the Type
+ * parameter set correctly for all 120,000+ lines.  As a result
+ * it is not possible to enforce the presence test throughout
+ * the entire script.
+ */
 int nb_qpathinfo(char *fname, int Type)
 {
     pstring path;
     int     rc;
     char    FileName[128];
     char    temp[512];
-static Flag = 0;
-
-    if (Type == 1111)
-        Flag = 1;
+    DWORD   gle;
+
+    if (Type == 1111) {
+        EnforcePathInfoErrors = 1;
+        Type = 1;
+    } else if (Type == 1001) {
+        EnforcePathInfoErrors = 0;
+        Type = 1;
+    } else if (Type == 1000) {
+        EnforcePathInfoErrors = 0;
+        Type = 0;
+    } else if (Type == 1110) {
+        EnforcePathInfoErrors = 1;
+        Type = 0;
+    }
 
     sprintf(FileName, "Thread_%05d.log", ProcessNumber);
 
@@ -783,7 +796,8 @@ static Flag = 0;
 
     StartFirstTimer();
     rc = GetPathInfo(path, NULL, NULL, NULL, NULL, NULL);
-
+    if (rc == 0)
+        gle = GetLastError();
     if (strstr(fname, "~TS"))
     {
         if (rc == 0)
@@ -792,31 +806,31 @@ static Flag = 0;
             rc = 0;
     }
 
-if (!Flag)
-{
-    if (Type)
+    if (!EnforcePathInfoErrors)
     {
-        if (rc)
-            rc = 0;
-        else
-            rc = 1;
-    }
-    if (!rc)
-    {
-        EndFirstTimer(CMD_QUERY_PATH_INFO, 0);
-        LeaveThread(0, "", CMD_QUERY_PATH_INFO);
-        sprintf(temp, "File: qpathinfo failed for %s\n", path);
-        if (verbose)
-            printf("%s", temp);
-        LogMessage(ProcessNumber, HostName, FileName, temp, LogID);
-        return(-1);
+        if (Type)
+        {
+            if (rc)
+                rc = 0;
+            else
+                rc = 1;
+        }
+        if (!rc)
+        {
+            EndFirstTimer(CMD_QUERY_PATH_INFO, 0);
+            LeaveThread(0, "", CMD_QUERY_PATH_INFO);
+            sprintf(temp, "File: qpathinfo failed for %s type %d GLE(0x%x)\n", path, Type, gle);
+            if (verbose)
+                printf("%s", temp);
+            LogMessage(ProcessNumber, HostName, FileName, temp, LogID);
+            return(-1);
+        }
     }
-}
     EndFirstTimer(CMD_QUERY_PATH_INFO, 1);
     return(0);
 }
 
-int nb_qfileinfo(int fnum)
+int nb_qfileinfo(int handle)
 {
     int     i;
     int     rc;
@@ -825,7 +839,7 @@ int nb_qfileinfo(int fnum)
 
     sprintf(FileName, "Thread_%05d.log", ProcessNumber);
 
-    if ((i = FindHandle(fnum)) == -1)
+    if ((i = FindHandle(handle)) == -1)
         return(-1);
 
     StartFirstTimer();
@@ -835,7 +849,7 @@ int nb_qfileinfo(int fnum)
     {
         EndFirstTimer(CMD_QUERY_FILE_INFO, 0);
         LeaveThread(0, "", CMD_QUERY_FILE_INFO);
-        sprintf(temp, "File: qfileinfo failed for %s\n", ftable[i].name);
+        sprintf(temp, "File: qfileinfo failed for %s GLE(0x%x)\n", ftable[i].name, GetLastError());
         if (verbose)
             printf("%s", temp);
         LogMessage(ProcessNumber, HostName, FileName, temp, LogID);
@@ -871,7 +885,7 @@ int nb_qfsinfo(int level)
     {
         EndFirstTimer(CMD_QUERY_FS_INFO, 0);
         LeaveThread(0, "", CMD_QUERY_FS_INFO);
-        strcpy(temp, "File: Disk free space failed\n");
+        sprintf(temp, "File: Disk free space failed GLE(0x%x)\n", GetLastError());
         if (verbose)
             printf("%s", temp);
         LogMessage(ProcessNumber, HostName, FileName, temp, LogID);
@@ -919,14 +933,15 @@ int nb_findfirst(char *mask)
     return(0);
 }
 
-int nb_flush(int fnum)
+int nb_flush(int handle)
 {
     int i;
 
-    if ((i = FindHandle(fnum)) == -1)
+    if ((i = FindHandle(handle)) == -1)
         return(-1);
+
+    FlushFileBuffers(ftable[i].fd);
     return(0);
-       /* hmmm, we don't have cli_flush() yet */
 }
 
 static int total_deleted;
@@ -954,7 +969,7 @@ void delete_fn(file_info *finfo, const char *name, void *state)
         if (!rc)
         {
             LeaveThread(0, "", CMD_UNLINK);
-            sprintf(temp, "FILE: DeleteFile %s failed\n", name);
+            sprintf(temp, "FILE: DeleteFile %s failed GLE(0x%x)\n", name, GetLastError());
             if (verbose)
                 printf("%s", temp);
             LogMessage(ProcessNumber, HostName, FileName, temp, LogID);
@@ -1151,9 +1166,9 @@ void EndSecondTime(int cmd)
 }
 
 
-int SystemCall(char *command)
+intptr_t SystemCall(char *command)
 {
-    int     rc;
+    intptr_t rc;
     char    *argv[6];
 
     argv[0] = getenv("COMSPEC");
@@ -1167,20 +1182,29 @@ int SystemCall(char *command)
     return(rc);
 }
 
-int CreateObject(const char *fname, uint32 DesiredAccess,
+HANDLE CreateObject(const char *fname, uint32 DesiredAccess,
                 uint32 FileAttributes, uint32 ShareAccess,
                 uint32 CreateDisposition, uint32 CreateOptions)
 {
-    int   fd;
+    HANDLE   fd;
     DWORD dwCreateDisposition = 0;
     DWORD dwDesiredAccess = 0;
     DWORD dwShareAccess = 0;
+    DWORD dwFlags = 0;
 
     if (CreateOptions & FILE_DIRECTORY_FILE)
     {
-        fd = CreateDirectory(fname, NULL);
-        if (fd == 0)
-            fd = -1;
+        DWORD rc;
+
+        if (!CreateDirectory(fname, NULL) && (rc = GetLastError()) != ERROR_ALREADY_EXISTS) 
+        {
+            SetLastError(rc);
+            fd = INVALID_HANDLE_VALUE;
+        }
+        else
+        {
+            fd = CreateFile(fname, 0, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+        }
     }
     else
     {
@@ -1194,21 +1218,21 @@ int CreateObject(const char *fname, uint32 DesiredAccess,
         dwCreateDisposition = OPEN_ALWAYS;
         if (CreateDisposition == 1)
             dwCreateDisposition = OPEN_EXISTING;
-        fd = (int)CreateFile(fname, dwDesiredAccess, ShareAccess, NULL, dwCreateDisposition, FILE_ATTRIBUTE_NORMAL, NULL);
+        fd = CreateFile(fname, dwDesiredAccess, ShareAccess, NULL, dwCreateDisposition, FILE_ATTRIBUTE_NORMAL, NULL);
     }
 
     return(fd);
 }
 
-BOOL nb_close1(int fnum)
+BOOL nb_close1(HANDLE fd)
 {
     int dwFlags = 0;
     int rc = 1;
 
-    if (fnum > 0)
+    if (fd != INVALID_HANDLE_VALUE)
     {
-        if (rc = GetHandleInformation((HANDLE)fnum, &dwFlags))
-            CloseHandle((HANDLE)fnum);
+        if (rc = GetHandleInformation(fd, &dwFlags))
+            CloseHandle(fd);
     }
     return(rc);
 }
@@ -1220,15 +1244,15 @@ BOOL nb_close1(int fnum)
   ****************************************************************************/
 int nb_list_old(const char *Mask, void (*fn)(file_info *, const char *, void *), void *state)
 {
-       int     num_received = 0;
-       pstring mask;
+    int     num_received = 0;
+    pstring mask;
     char    temp[512];
     char    cFileName[1024];
     int     dwFileAttributes;
     HANDLE  hFind;
     void    *FileData;
 
-       strcpy(mask,Mask);
+    strcpy(mask,Mask);
 
 
     if (!strcmp(&mask[strlen(mask)-2], "\"*"))
@@ -1361,7 +1385,6 @@ BOOL GetPathInfo(const char *fname,
     SYSTEMTIME  SystemTime;
     struct tm   tm_time;
 
-//    rc = WinGetFileAttributesEx(UseUnicode, (char *)fname, &FileInfo);
     rc = GetFileAttributesEx(fname, GetFileExInfoStandard, &FileInfo);
     if (rc != 0)
     {
@@ -1401,7 +1424,7 @@ BOOL GetPathInfo(const char *fname,
 /****************************************************************************
 send a qfileinfo call
 ****************************************************************************/
-BOOL GetFileInfo(char *FileName, int fnum, 
+BOOL GetFileInfo(char *FileName, HANDLE fd, 
                    uint16 *mode, size_t *size,
                    time_t *c_time, time_t *a_time, time_t *m_time, 
                    time_t *w_time)
@@ -1451,23 +1474,23 @@ BOOL GetFileInfo(char *FileName, int fnum,
   Read size bytes at offset offset using SMBreadX.
 ****************************************************************************/
 
-ssize_t nb_read(int fnum, char *IoBuffer, off_t offset, size_t size)
+ssize_t nb_read(HANDLE fd, char *IoBuffer, off_t offset, size_t size)
 {
-       ssize_t total = 0;
+    DWORD   total = 0;
     int     rc;
     DWORD   LowDword;
 
-       if (size == 0) 
-               return(0);
+    if (size == 0) 
+        return(0);
 
-    LowDword = SetFilePointer((HANDLE)fnum, offset, 0, FILE_BEGIN);
+    LowDword = SetFilePointer(fd, offset, 0, FILE_BEGIN);
 
     if (LowDword == INVALID_SET_FILE_POINTER)
         return(-1);
-    rc = ReadFile((HANDLE)fnum, IoBuffer, size, &total, NULL);
-
+    rc = ReadFile(fd, IoBuffer, (DWORD)size, &total, NULL);
     if (!rc)
         return(rc);
+
     return(total);
 }
 
@@ -1475,19 +1498,19 @@ ssize_t nb_read(int fnum, char *IoBuffer, off_t offset, size_t size)
   write to a file
 ****************************************************************************/
 
-ssize_t nb_write(int fnum, char *IoBuffer, off_t offset, size_t size)
+ssize_t nb_write(HANDLE fd, char *IoBuffer, off_t offset, size_t size)
 {
-       int     bwritten = 0;
+    DWORD   bwritten = 0;
     int     rc;
     DWORD   LowDword;
 
-    LowDword = SetFilePointer((HANDLE)fnum, offset, 0, FILE_BEGIN);
+    LowDword = SetFilePointer(fd, offset, 0, FILE_BEGIN);
     if (LowDword == INVALID_SET_FILE_POINTER)
         return(-1);
-    rc = WriteFile((HANDLE)fnum, IoBuffer, size, &bwritten, NULL);
-
+    rc = WriteFile(fd, IoBuffer, (DWORD)size, &bwritten, NULL);
     if (!rc)
         return(rc);
-    FlushFileBuffers((HANDLE)fnum);
+    FlushFileBuffers(fd);
     return(bwritten);
 }
+