platform/win32.c
changeset 606 70cf47819dd2
parent 596 381b6ca0dd85
child 615 53f0d8be2b39
equal deleted inserted replaced
605:54abd19652fa 606:70cf47819dd2
    27     #define alloca(x) _alloca(x)
    27     #define alloca(x) _alloca(x)
    28 #elif (defined MINGW)  /* scary...hopefully this is okay. */
    28 #elif (defined MINGW)  /* scary...hopefully this is okay. */
    29     #define alloca(x) __builtin_alloca(x) 
    29     #define alloca(x) __builtin_alloca(x) 
    30 #endif
    30 #endif
    31 
    31 
    32 #define LOWORDER_UINT64(pos)       (PHYSFS_uint32)(pos & 0x00000000FFFFFFFF)
    32 #define LOWORDER_UINT64(pos) (PHYSFS_uint32) \
    33 #define HIGHORDER_UINT64(pos)      (PHYSFS_uint32)(pos & 0xFFFFFFFF00000000)
    33     (pos & 0x00000000FFFFFFFF)
       
    34 #define HIGHORDER_UINT64(pos) (PHYSFS_uint32) \
       
    35     (((pos & 0xFFFFFFFF00000000) >> 32) & 0x00000000FFFFFFFF)
    34 
    36 
    35 /* GetUserProfileDirectory() is only available on >= NT4 (no 9x/ME systems!) */
    37 /* GetUserProfileDirectory() is only available on >= NT4 (no 9x/ME systems!) */
    36 typedef BOOL (STDMETHODCALLTYPE FAR * LPFNGETUSERPROFILEDIR) (
    38 typedef BOOL (STDMETHODCALLTYPE FAR * LPFNGETUSERPROFILEDIR) (
    37       HANDLE hToken,
    39       HANDLE hToken,
    38       LPTSTR lpProfileDir,
    40       LPTSTR lpProfileDir,
    58 /*
    60 /*
    59  * Users without the platform SDK don't have this defined.  The original docs
    61  * Users without the platform SDK don't have this defined.  The original docs
    60  *  for SetFilePointer() just said to compare with 0xFFFFFFFF, so this should
    62  *  for SetFilePointer() just said to compare with 0xFFFFFFFF, so this should
    61  *  work as desired
    63  *  work as desired
    62  */
    64  */
    63 #ifndef INVALID_SET_FILE_POINTER
    65 #define PHYSFS_INVALID_SET_FILE_POINTER  0xFFFFFFFF
    64 #  define INVALID_SET_FILE_POINTER  0xFFFFFFFF
       
    65 #endif
       
    66 
    66 
    67 /* just in case... */
    67 /* just in case... */
    68 #ifndef INVALID_FILE_ATTRIBUTES
    68 #define PHYSFS_INVALID_FILE_ATTRIBUTES   0xFFFFFFFF
    69 #  define INVALID_FILE_ATTRIBUTES   0xFFFFFFFF
    69 
    70 #endif
       
    71 
    70 
    72 
    71 
    73 /*
    72 /*
    74  * Figure out what the last failing Win32 API call was, and
    73  * Figure out what the last failing Win32 API call was, and
    75  *  generate a human-readable string for the error message.
    74  *  generate a human-readable string for the error message.
   254 {
   253 {
   255     UINT oldErrorMode;
   254     UINT oldErrorMode;
   256     DWORD tmp;
   255     DWORD tmp;
   257     BOOL retval;
   256     BOOL retval;
   258 
   257 
   259     /* Prevent windows warning message to appear when checking media size */
   258     /* Prevent windows warning message appearing when checking media size */
   260     oldErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS);
   259     oldErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS);
   261     
   260     
   262     /* If this function succeeds, there's media in the drive */
   261     /* If this function succeeds, there's media in the drive */
   263     retval = GetVolumeInformation(drive, NULL, 0, NULL, NULL, &tmp, NULL, 0);
   262     retval = GetVolumeInformation(drive, NULL, 0, NULL, NULL, &tmp, NULL, 0);
   264 
   263 
   396 } /* __PHYSFS_platformStricmp */
   395 } /* __PHYSFS_platformStricmp */
   397 
   396 
   398 
   397 
   399 int __PHYSFS_platformExists(const char *fname)
   398 int __PHYSFS_platformExists(const char *fname)
   400 {
   399 {
   401     BAIL_IF_MACRO(GetFileAttributes(fname) == INVALID_FILE_ATTRIBUTES,
   400     BAIL_IF_MACRO
   402                   win32strerror(), 0);
   401     (
       
   402         GetFileAttributes(fname) == PHYSFS_INVALID_FILE_ATTRIBUTES,
       
   403         win32strerror(), 0
       
   404     );
   403     return(1);
   405     return(1);
   404 } /* __PHYSFS_platformExists */
   406 } /* __PHYSFS_platformExists */
   405 
   407 
   406 
   408 
   407 int __PHYSFS_platformIsSymLink(const char *fname)
   409 int __PHYSFS_platformIsSymLink(const char *fname)
   477 
   479 
   478     /* Append the "*" to the end of the string */
   480     /* Append the "*" to the end of the string */
   479     strcat(SearchPath, "*");
   481     strcat(SearchPath, "*");
   480 
   482 
   481     dir = FindFirstFile(SearchPath, &ent);
   483     dir = FindFirstFile(SearchPath, &ent);
   482     BAIL_IF_MACRO(dir == INVALID_HANDLE_VALUE, win32strerror(), NULL);
   484     BAIL_IF_MACRO
       
   485     (
       
   486         dir == PHYSFS_INVALID_HANDLE_VALUE,
       
   487         win32strerror(), NULL
       
   488     );
   483 
   489 
   484     do
   490     do
   485     {
   491     {
   486         if (strcmp(ent.cFileName, ".") == 0)
   492         if (strcmp(ent.cFileName, ".") == 0)
   487             continue;
   493             continue;
   740     win32file *retval;
   746     win32file *retval;
   741 
   747 
   742     fileHandle = CreateFile(fname, mode, FILE_SHARE_READ, NULL,
   748     fileHandle = CreateFile(fname, mode, FILE_SHARE_READ, NULL,
   743                             creation, FILE_ATTRIBUTE_NORMAL, NULL);
   749                             creation, FILE_ATTRIBUTE_NORMAL, NULL);
   744 
   750 
   745     BAIL_IF_MACRO(fileHandle == INVALID_HANDLE_VALUE, win32strerror(), NULL);
   751     BAIL_IF_MACRO
       
   752     (
       
   753         fileHandle == PHYSFS_INVALID_HANDLE_VALUE,
       
   754         win32strerror(), NULL
       
   755     );
   746 
   756 
   747     retval = malloc(sizeof (win32file));
   757     retval = malloc(sizeof (win32file));
   748     if (retval == NULL)
   758     if (retval == NULL)
   749     {
   759     {
   750         CloseHandle(fileHandle);
   760         CloseHandle(fileHandle);
   773 {
   783 {
   774     void *retval = doOpen(filename, GENERIC_WRITE, OPEN_ALWAYS, 0);
   784     void *retval = doOpen(filename, GENERIC_WRITE, OPEN_ALWAYS, 0);
   775     if (retval != NULL)
   785     if (retval != NULL)
   776     {
   786     {
   777         HANDLE h = ((win32file *) retval)->handle;
   787         HANDLE h = ((win32file *) retval)->handle;
   778         if (SetFilePointer(h, 0, NULL, FILE_END) == INVALID_SET_FILE_POINTER)
   788         DWORD rc = SetFilePointer(h, 0, NULL, FILE_END);
       
   789         if (rc == PHYSFS_INVALID_SET_FILE_POINTER)
   779         {
   790         {
   780             const char *err = win32strerror();
   791             const char *err = win32strerror();
   781             CloseHandle(h);
   792             CloseHandle(h);
   782             free(retval);
   793             free(retval);
   783             BAIL_MACRO(err, NULL);
   794             BAIL_MACRO(err, NULL);
   838 
   849 
   839 int __PHYSFS_platformSeek(void *opaque, PHYSFS_uint64 pos)
   850 int __PHYSFS_platformSeek(void *opaque, PHYSFS_uint64 pos)
   840 {
   851 {
   841     HANDLE FileHandle = ((win32file *) opaque)->handle;
   852     HANDLE FileHandle = ((win32file *) opaque)->handle;
   842     DWORD HighOrderPos;
   853     DWORD HighOrderPos;
       
   854     DWORD *pHighOrderPos;
   843     DWORD rc;
   855     DWORD rc;
   844 
   856 
   845     /* Get the high order 32-bits of the position */
   857     /* Get the high order 32-bits of the position */
   846     HighOrderPos = HIGHORDER_UINT64(pos);
   858     HighOrderPos = HIGHORDER_UINT64(pos);
   847 
   859 
   848     /* !!! FIXME: SetFilePointer needs a signed 64-bit value. */
   860     /*
       
   861      * MSDN: "If you do not need the high-order 32 bits, this
       
   862      *         pointer must be set to NULL."
       
   863      */
       
   864     pHighOrderPos = (HighOrderPos) ? &HighOrderPos : NULL;
       
   865 
       
   866     /*
       
   867      * !!! FIXME: MSDN: "Windows Me/98/95:  If the pointer
       
   868      * !!! FIXME:  lpDistanceToMoveHigh is not NULL, then it must
       
   869      * !!! FIXME:  point to either 0, INVALID_SET_FILE_POINTER, or
       
   870      * !!! FIXME:  the sign extension of the value of lDistanceToMove.
       
   871      * !!! FIXME:  Any other value will be rejected."
       
   872      */
       
   873 
   849     /* Move pointer "pos" count from start of file */
   874     /* Move pointer "pos" count from start of file */
   850     rc = SetFilePointer(FileHandle, LOWORDER_UINT64(pos),
   875     rc = SetFilePointer(FileHandle, LOWORDER_UINT64(pos),
   851                         &HighOrderPos, FILE_BEGIN);
   876                         pHighOrderPos, FILE_BEGIN);
   852 
   877 
   853     if ((rc == INVALID_SET_FILE_POINTER) && (GetLastError() != NO_ERROR))
   878     if ( (rc == PHYSFS_INVALID_SET_FILE_POINTER) &&
       
   879          (GetLastError() != NO_ERROR) )
       
   880     {
   854         BAIL_MACRO(win32strerror(), 0);
   881         BAIL_MACRO(win32strerror(), 0);
   855 
   882     } /* if */
       
   883     
   856     return(1);  /* No error occured */
   884     return(1);  /* No error occured */
   857 } /* __PHYSFS_platformSeek */
   885 } /* __PHYSFS_platformSeek */
   858 
   886 
   859 
   887 
   860 PHYSFS_sint64 __PHYSFS_platformTell(void *opaque)
   888 PHYSFS_sint64 __PHYSFS_platformTell(void *opaque)
   864     DWORD LowPos;
   892     DWORD LowPos;
   865     PHYSFS_sint64 retval;
   893     PHYSFS_sint64 retval;
   866 
   894 
   867     /* Get current position */
   895     /* Get current position */
   868     LowPos = SetFilePointer(FileHandle, 0, &HighPos, FILE_CURRENT);
   896     LowPos = SetFilePointer(FileHandle, 0, &HighPos, FILE_CURRENT);
   869     if ((LowPos == INVALID_SET_FILE_POINTER) && (GetLastError() != NO_ERROR))
   897     if ( (LowPos == PHYSFS_INVALID_SET_FILE_POINTER) &&
       
   898          (GetLastError() != NO_ERROR) )
   870     {
   899     {
   871         BAIL_MACRO(win32strerror(), 0);
   900         BAIL_MACRO(win32strerror(), 0);
   872     } /* if */
   901     } /* if */
   873     else
   902     else
   874     {
   903     {
   887     DWORD SizeHigh;
   916     DWORD SizeHigh;
   888     DWORD SizeLow;
   917     DWORD SizeLow;
   889     PHYSFS_sint64 retval;
   918     PHYSFS_sint64 retval;
   890 
   919 
   891     SizeLow = GetFileSize(FileHandle, &SizeHigh);
   920     SizeLow = GetFileSize(FileHandle, &SizeHigh);
   892     if ((SizeLow == INVALID_SET_FILE_POINTER) && (GetLastError() != NO_ERROR))
   921     if ( (SizeLow == PHYSFS_INVALID_SET_FILE_POINTER) &&
       
   922          (GetLastError() != NO_ERROR) )
   893     {
   923     {
   894         BAIL_MACRO(win32strerror(), -1);
   924         BAIL_MACRO(win32strerror(), -1);
   895     } /* if */
   925     } /* if */
   896     else
   926     else
   897     {
   927     {