/* * pmdos.c * * Copyright (c) 1991, Microsoft Corporation * * DESCRIPTION * * This file is for support of program manager under NT Windows. * This file is/was ported from pmdos.asm (program manager). * It was in x86 asm code, and now is in ansi C. * Some functions will be removed, due to they are only needed * by DOS Windows. * * MODIFICATION HISTORY * Initial Version: x/x/90 Author Unknown, since he didn't feel * like commenting the code... * * NT 32b Version: 1/9/91 Jeff Pack * Intitial port to begin. * * WARNING: since this is NOT for DOS, I'm making it soley 32bit aware. * Following functions not ported * IsRemovable() is in pmcomman.c (already ifdef'd in asm code) * IsRemote() is in pmcomman.c (ditto!) * */ #ifndef ORGCODE #include #include #include #endif #include "windows.h" #include BOOL PathType(LPSTR); DWORD FileTime(HFILE); DWORD GetDOSErrorCode(VOID); int GetCurrentDrive(VOID); int w_GetCurrentDirectory(int, LPSTR); int w_SetCurrentDirectory(LPSTR); int DosDelete(LPSTR); LPSTR lmemmove(LPSTR, LPSTR, WORD); BOOL FAR PASCAL IsRemoteDrive(int); BOOL FAR PASCAL IsRemovableDrive(int); #define LOCALBUFFERSIZE 128 /*** PathType -- Determines if string denotes a directory or not. * * * * BOOL PathType(LPSTR pszFileString) * * ENTRY - LPSTR pszFileString - pointer to string to use to determine if directory * or not. * window, with focus. * EXIT - int iReturnValue - 2 = is directory 1 = Is Not directory * * SYNOPSIS - This function takes a pointer to a string, calls OS to determine * if string is, or is not a directory. * WARNINGS - Cna't even see where this is called! * EFFECTS - * */ BOOL PathType(LPSTR lpszFileString) { LPSTR lpszLocalBuffer; /*local buffer for AnsiToOem()*/ DWORD dwReturnedAttributes; DWORD nBufferLength; nBufferLength = strlen(lpszFileString) + 1; /*alloc local, non-moveable, zero filled buffer*/ lpszLocalBuffer = LocalAlloc(LMEM_ZEROINIT, nBufferLength); if(lpszLocalBuffer == NULL){ #if DBG OutputDebugString(" LocalAlloc FAILed\n"); #endif /* DBG */ return 0; } AnsiToOem(lpszFileString, lpszLocalBuffer); /*get attributes of filestring*/ dwReturnedAttributes = GetFileAttributes(lpszLocalBuffer); if(dwReturnedAttributes == -1){ #if DBG OutputDebugString(" - GetFileAttributes() FAILed!\n"); #endif /* DBG */ LocalFree(lpszLocalBuffer); return(0); } else{ /*and with directory attribute*/ dwReturnedAttributes = dwReturnedAttributes & FILE_ATTRIBUTE_DIRECTORY; switch(dwReturnedAttributes){ case FILE_ATTRIBUTE_DIRECTORY: LocalFree(lpszLocalBuffer); return(2); break; default: LocalFree(lpszLocalBuffer); return(1); } } } /*** FileTime -- Gets time of last modification. * * * * DWORD FileTime(HFILE hFile) * * ENTRY - int hFile - file handle to access * * EXIT - LPWORD - which is gotten from lpTimeStamp = 0 (ERROR). * or lpTimeStamp != 0 (value of timestamp) * * SYNOPSIS - calls GetFileTime() to get timestamp. If error, then * lpTimeStamp = 0, else contains TimeStamp for file. * WARNINGS - * EFFECTS - * */ DWORD FileTime( HFILE hFile) { BOOL bReturnCode; FILETIME CreationTime; FILETIME LastAccessTime; FILETIME LastWriteTime; WORD FatTime = 0; WORD FatDate; bReturnCode = GetFileTime(LongToHandle(hFile), &CreationTime, &LastAccessTime, &LastWriteTime); /* * Test return code */ if (bReturnCode == FALSE) { return 0; /*set to zero, for error*/ } /* * Now convert 64bit time to DOS 16bit time */ FileTimeToDosDateTime( &LastWriteTime, &FatDate, &FatTime); return FatTime; } /*** IsReadOnly -- determines if file is readonly or not. * * * * BOOL IsReadOnly(LPSTR lpszFileString) * * ENTRY - LPSTR lpszFileString - file name to use * * EXIT - BOOL xxx - returns (0) = not readonly (1) = read only * or lpTimeStamp != 0 (value of timestamp) * * SYNOPSIS - calls GetAttributes, then tests if file is read only. * WARNINGS - * EFFECTS - * */ BOOL IsReadOnly(LPSTR lpszFileString) { DWORD dwReturnedAttributes; LPSTR lpszLocalBuffer; /*local buffer for AnsiToOem()*/ DWORD nBufferLength; nBufferLength = strlen(lpszFileString) + 1; /*alloc local, non-moveable, zero filled buffer*/ lpszLocalBuffer = LocalAlloc(LMEM_ZEROINIT, nBufferLength); if(lpszLocalBuffer == NULL){ #if DBG OutputDebugString(" LocalAlloc FAILed\n"); #endif /* DBG */ return 0; } AnsiToOem(lpszFileString, lpszLocalBuffer); /*get attributes of filestring*/ dwReturnedAttributes = GetFileAttributes(lpszLocalBuffer); if(dwReturnedAttributes == -1){ #if DBG OutputDebugString(" - GetFileAttributes() FAILed!\n"); #endif /* DBG */ LocalFree(lpszLocalBuffer); return FALSE; } else { /*AND with read_only attribute*/ dwReturnedAttributes = dwReturnedAttributes & FILE_ATTRIBUTE_READONLY; switch(dwReturnedAttributes){ case FILE_ATTRIBUTE_READONLY: LocalFree(lpszLocalBuffer); return TRUE; break; default: LocalFree(lpszLocalBuffer); return FALSE; } } } /*** GetDOSErrorCode -- returns extended error code * * * * DWORD GetDOSErrorCode(VOID) * * ENTRY - VOID * * EXIT - DWORD - returned extended code. * * SYNOPSIS - calls GetLastError() to get error code from OS * WARNINGS - * EFFECTS - * */ DWORD GetDOSErrorCode(VOID) { return( (int) GetLastError()); /*BUG BUG, pmgseg.c uses this from _lcreat() to determine if returned 5 (access denied) or 13 (invalid_data). So this need be tested to see if win32 returns these.*/ } /*** GetCurrentDrive -- get current drive number. * * * * int GetCurrentDrive(VOID) * * ENTRY - VOID * * EXIT - int CurrentDrive - drive number of current drive (0=a, etc). * * SYNOPSIS - calls GetCurrentDirectory, must parse returned string * for either drive letter, or UNC path. If UNC I gotta * somehow, covert UNC path to drive letter to drive number. * WARNINGS - * EFFECTS - * */ int GetCurrentDrive(VOID) { /*BUG BUG, not DBCS aware!*/ DWORD nBufferLength = LOCALBUFFERSIZE; DWORD dwReturnCode; LPSTR lpszLocalBuffer; int iDriveNumber; /*alloc local, non-moveable, zero filled buffer*/ lpszLocalBuffer = LocalAlloc(LMEM_ZEROINIT, nBufferLength); if(lpszLocalBuffer == NULL){ #if DBG OutputDebugString(" LocalAlloc FAILed\n"); #endif /* DBG */ return 0; } GetCurDrive1: dwReturnCode = GetCurrentDirectory(nBufferLength, lpszLocalBuffer); /*failed for reason other than bufferlength too small*/ if(dwReturnCode == 0){ #if DBG OutputDebugString(" GetCurrentDirectory() FAILed\n"); #endif /* DBG */ return 0; } /*test for success, if dwReturnCode is > buffer, then need increase buffer*/ if(dwReturnCode > nBufferLength){ lpszLocalBuffer = LocalReAlloc(lpszLocalBuffer, nBufferLength + LOCALBUFFERSIZE, LMEM_ZEROINIT | LMEM_MOVEABLE); if(lpszLocalBuffer == NULL){ #if DBG OutputDebugString(" LocalAlloc FAILed\n"); #endif /* DBG */ return 0; } else{ nBufferLength += LOCALBUFFERSIZE; } goto GetCurDrive1; } /*finally lpszLocalBuffer has string containing current directory*/ /* now must parse string for ":" or "\\" for drive letter or UNC*/ /*if : then get drive letter, and convert to number a=0, b=1, etc.*/ /*if \\ then gotta enumerate net drives, to learn what drive letter*/ /*corresponds to that UNC path*/ /*check for drive letter*/ if(lpszLocalBuffer[1] == ':'){ /*is drive letter, proceed*/ if(isupper(lpszLocalBuffer[0])){ iDriveNumber = lpszLocalBuffer[0] - 'A'; /*convert letter > number*/ } else{ iDriveNumber = lpszLocalBuffer[0] - 'a'; /*convert letter > number*/ } } else{ /*must be UNC path*/ /*BUG BUG need write code to convert UNC path */ #if DBG OutputDebugString(" Got UNC path, didnt expect, and no code!\n"); #endif /* DBG */ } LocalFree(lpszLocalBuffer); return(iDriveNumber); } /*** SetCurrentDrive -- set current drive. * * * * int SetCurrentDrive(int iDrive) * * ENTRY - int iDrive - drive number to set as current drive * * EXIT - int xxx - under DOS would have returned # of logical drives. * I can do this, but it's not used, if fact, no error * checks are done on this return value. * * SYNOPSIS - calls SetCurrentDirectory to set current drive. * WARNINGS - ALWAYS sets to root directory, since can't get cur dir * on other than current working drive. * EFFECTS - * */ int SetCurrentDrive(int iDrive) { char cLocalBuffer[LOCALBUFFERSIZE] = "C:\\"; char cDriveLetter; /*convert drive number (zero based) to letter*/ cDriveLetter = (char) iDrive + (char)'A'; cLocalBuffer[0] = cDriveLetter; /*set new drive in string*/ if(!SetCurrentDirectory(cLocalBuffer)){ /*call failed*/ #if DBG OutputDebugString(" SetCurrentDirectory FAILed!\n"); #endif /* DBG */ return 0; } return(0); } /*** w_GetCurrentDirectory -- GetCurrent Working Directory * * * * int w_GetCurrentDirectory(int iDrive, LPSTR lpszCurrentDirectory) * * ENTRY - int iDrive - drive number to use as current drive. * LPSTR lpszCurrentDirectory - pointer to return data to. * * EXIT - int iReturnCode - returns (0) if success * LPSTR lpszCurrentDirectory - has curretn directory. * * SYNOPSIS - calls GetCurrentDirectory to get current directory. * the original asm code, checked idrive for zero, if so * then calls GetCurrentDrive. Under win32, is not neccessary, * since GetCUrrentDirectory() returns current drive. * Since it checks this, it means then that other than current * drive can be checked, yet win32 doesnt allow this, so I have to * code in a debug check, if iDrive != current drive. * WARNINGS - win32 doesn't allow multiple cur dirs across drives. * EFFECTS - * */ int w_GetCurrentDirectory(int iDrive, LPSTR lpszCurrentDirectory) { /*first see if iDrive == 0, if so then only need call GetCurrentDirectory*/ /*if non-zero, then could be current drive, OR another drive.*/ /*THIS IS NOT ALLOWED!*/ /*BUG BUG, not DBCS aware!*/ DWORD nBufferLength = LOCALBUFFERSIZE; DWORD dwReturnCode; LPSTR lpszLocalBuffer; int iDriveNumber; /*alloc local, non-moveable, zero filled buffer*/ lpszLocalBuffer = LocalAlloc(LMEM_ZEROINIT, nBufferLength); if(lpszLocalBuffer == NULL){ #if DBG OutputDebugString(" LocalAlloc FAILed\n"); #endif /* DBG */ return(1); } GetCurDir1: dwReturnCode = GetCurrentDirectory(nBufferLength, lpszLocalBuffer); /*failed for reason other than bufferlength too small*/ if(dwReturnCode == 0){ #if DBG OutputDebugString(" GetCurrentDirectory() FAILed\n"); #endif /* DBG */ LocalFree(lpszLocalBuffer); return(1); } /*test for success, if dwReturnCode is > buffer, then need increase buffer*/ if(dwReturnCode > nBufferLength){ lpszLocalBuffer = LocalReAlloc(lpszLocalBuffer, nBufferLength + LOCALBUFFERSIZE, LMEM_ZEROINIT | LMEM_MOVEABLE); if(lpszLocalBuffer == NULL){ #if DBG OutputDebugString(" LocalAlloc FAILed\n"); #endif /* DBG */ LocalFree(lpszLocalBuffer); return(1); } else{ nBufferLength += LOCALBUFFERSIZE; } goto GetCurDir1; } /*now I have string that contains EITHER current drive in a drive letter*/ /*or current drive by a UNC name*/ /*BUG BUG UNC name check uncoded, since I have to go from UNC name to drive letter*/ /*debug code, to make sure iDrive == current drive*/ /*see if drive letter based string*/ if(lpszLocalBuffer[1] == ':'){ /*is Drive letter based!*/ /*never know case of returned string from kernel*/ if(isupper(lpszLocalBuffer[0])){ iDriveNumber = lpszLocalBuffer[0] - 'A'; } else{ iDriveNumber = lpszLocalBuffer[0] - 'a'; } /*DEBUG make sure that we are indeed setting a new drive */ /* remember that iDrive == 0 means use current drive!*/ if(iDrive == iDriveNumber || iDrive == 0){ /*is current drive and drive letter based, set to after "x:\"*/ strcpy(lpszCurrentDirectory, lpszLocalBuffer); /*copy directory to pointer*/ } else{ /* is different drive, or not using current drive (== 0)*/ SetCurrentDrive(iDriveNumber); /*set new drive ":\" */ /*now that new drive/dir is set, return current dir*/ /* BUG BUG, because setting drive, overides cur dir, I return*/ /* ":\" */ strcpy(lpszCurrentDirectory, "c:\\"); lpszCurrentDirectory[0] = (char) (iDriveNumber + 'a'); /*set new drive*/ } } else{ /*is NOT drive letter based*/ /* BUG BUG need write code to parse UNC, and return only the path*/ /* BUG BUGalso need check to see if iDrive == UNC drive, so I gotta*/ /* convert UNC path to drive, and compare*/ #if DBG OutputDebugString(" Took path for UNC, and no code!\n"); #endif /* DBG */ LocalFree(lpszLocalBuffer); return(1); } LocalFree(lpszLocalBuffer); return(0); /*success*/ } /*** w_SetCurrentDirectory -- SetCurrent Working Directory and drive * * int w_SetCurrentDirectory(LPSTR lpszCurrentDirectory) * * ENTRY - LPSTR lpszCurrentDirectory - string to set current drive/dir to * * EXIT - int iReturnCode - returns (0) if success * * SYNOPSIS - calls SetCurrentDirectory to set current directory and drive. * WARNINGS - * EFFECTS - * */ int w_SetCurrentDirectory(LPSTR lpszCurrentDirectory) { DWORD dwReturnCode; dwReturnCode = SetCurrentDirectory(lpszCurrentDirectory); if(dwReturnCode == 0){ #if DBG OutputDebugString(" SetCurrentDirectory FAILed!\n"); #endif /* DBG */ return(1); } return(0); /*success*/ } /*** DosDelete -- Delete named file. * * int DosDelete(LPSTR lpszFileToDelete) * * ENTRY - LPSTR lpszFileToDelete - filename to delete. * * EXIT - int xxx - returns (0) if success * * SYNOPSIS - calls win32 DeleteFile. * WARNINGS - * EFFECTS - * */ int DosDelete(LPSTR lpszFileToDelete) { BOOL bReturnCode; LPSTR lpszLocalBuffer; /*local buffer for AnsiToOem()*/ DWORD nBufferLength; nBufferLength = strlen(lpszFileToDelete) + 1; /*alloc local, non-moveable, zero filled buffer*/ lpszLocalBuffer = LocalAlloc(LMEM_ZEROINIT, nBufferLength); if(lpszLocalBuffer == NULL){ #if DBG OutputDebugString(" LocalAlloc FAILed\n"); #endif /* DBG */ return 1; } AnsiToOem(lpszFileToDelete, lpszLocalBuffer); bReturnCode = DeleteFile(lpszLocalBuffer); LocalFree(lpszLocalBuffer); if(bReturnCode){ return(0); } else{ return(1); } } /*** DosRename -- Rename file. * * int DosRename(LPSTR lpszOrgFileName, LPSTR lpszNewFileName) * * ENTRY - LPSTR lpszOrgFileName - origianl filename. * LPSTR lpszNewFileName - New filename. * * EXIT - int xxx - returns (0) if success * * SYNOPSIS - calls win32 MoveFile. * WARNINGS - * EFFECTS - * */ int DosRename(LPSTR lpszOrgFileName, LPSTR lpszNewFileName) { BOOL bReturnCode; LPSTR lpszLocalBuffer; /*local buffer for AnsiToOem()*/ LPSTR lpszLocalBuffer1; /*local buffer for AnsiToOem()*/ DWORD nBufferLength; DWORD nBufferLength1; nBufferLength = strlen(lpszOrgFileName) + 1; nBufferLength1 = strlen(lpszNewFileName) + 1; /*alloc local, non-moveable, zero filled buffer*/ lpszLocalBuffer = LocalAlloc(LMEM_ZEROINIT, nBufferLength); if(lpszLocalBuffer == NULL){ #if DBG OutputDebugString(" LocalAlloc FAILed\n"); #endif /* DBG */ return 1; } lpszLocalBuffer1 = LocalAlloc(LMEM_ZEROINIT, nBufferLength1); if(lpszLocalBuffer1 == NULL){ OutputDebugString(" LocalAlloc FAILed\n"); } AnsiToOem(lpszOrgFileName, lpszLocalBuffer); AnsiToOem(lpszNewFileName, lpszLocalBuffer1); /*rename file*/ bReturnCode = MoveFile(lpszLocalBuffer, lpszLocalBuffer1); LocalFree(lpszLocalBuffer); LocalFree(lpszLocalBuffer1); if(bReturnCode){ return(0); } else{ return(1); } } /*** lmemmove -- move memory. * * LPSTR lmemmove(LPSTR lpszDst, LPSTR lpszSrc, WORD wCount) * * ENTRY - LPSTR lpszDst - destination * LPSTR lpszSrc - source * WORD wCount - number of chars to move. * * EXIT - LPSTR lpszDst - returns lpszDst. * * SYNOPSIS - calls c runtime. Done cause they hacked lmemove to asm. * WARNINGS - * EFFECTS - * */ LPSTR lmemmove(LPSTR lpszDst, LPSTR lpszSrc, WORD wCount) { return(memmove(lpszDst, lpszSrc, wCount)); }