/*++ Function: SetCurrentDirectoryA See MSDN doc. --*/ BOOL PALAPI SetCurrentDirectoryA( IN LPCSTR lpPathName) { BOOL bRet = FALSE; DWORD dwLastError = 0; int result; LPSTR UnixPathName = NULL; PERF_ENTRY(SetCurrentDirectoryA); ENTRY("SetCurrentDirectoryA(lpPathName=%p (%s))\n", lpPathName?lpPathName:"NULL", lpPathName?lpPathName:"NULL"); /*check if the given path is null. If so return FALSE*/ if (lpPathName == NULL ) { ERROR("Invalid path/directory name\n"); dwLastError = ERROR_INVALID_NAME; goto done; } if (strlen(lpPathName) >= MAX_LONGPATH) { WARN("Path/directory name longer than MAX_LONGPATH characters\n"); dwLastError = ERROR_FILENAME_EXCED_RANGE; goto done; } UnixPathName = PAL__strdup(lpPathName); if (UnixPathName == NULL ) { ERROR("PAL__strdup() failed\n"); dwLastError = ERROR_NOT_ENOUGH_MEMORY; goto done; } FILEDosToUnixPathA( UnixPathName ); TRACE("Attempting to open Unix dir [%s]\n", UnixPathName); result = chdir(UnixPathName); if ( result == 0 ) { bRet = TRUE; } else { if ( errno == ENOTDIR || errno == ENOENT ) { struct stat stat_data; if ( stat( UnixPathName, &stat_data) == 0 && (stat_data.st_mode & S_IFMT) == S_IFREG ) { /* Not a directory, it is a file. */ dwLastError = ERROR_DIRECTORY; } else { FILEGetProperNotFoundError( UnixPathName, &dwLastError ); } TRACE("chdir() failed, path was invalid.\n"); } else { dwLastError = ERROR_ACCESS_DENIED; ERROR("chdir() failed; errno is %d (%s)\n", errno, strerror(errno)); } } done: if( dwLastError ) { SetLastError(dwLastError); } if(UnixPathName != NULL) { PAL_free( UnixPathName ); } LOGEXIT("SetCurrentDirectoryA returns BOOL %d\n", bRet); PERF_EXIT(SetCurrentDirectoryA); return bRet; }
/*++ Function: CreateDirectoryA Note: lpSecurityAttributes always NULL. See MSDN doc. --*/ BOOL PALAPI CreateDirectoryA( IN LPCSTR lpPathName, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes) { BOOL bRet = FALSE; DWORD dwLastError = 0; char *realPath; LPSTR UnixPathName = NULL; int pathLength; int i; const int mode = S_IRWXU | S_IRWXG | S_IRWXO; PERF_ENTRY(CreateDirectoryA); ENTRY("CreateDirectoryA(lpPathName=%p (%s), lpSecurityAttr=%p)\n", lpPathName?lpPathName:"NULL", lpPathName?lpPathName:"NULL", lpSecurityAttributes); if ( lpSecurityAttributes ) { ASSERT("lpSecurityAttributes is not NULL as it should be\n"); dwLastError = ERROR_INVALID_PARAMETER; goto done; } // Windows returns ERROR_PATH_NOT_FOUND when called with NULL. // If we don't have this check, strdup(NULL) segfaults. if (lpPathName == NULL) { ERROR("CreateDirectoryA called with NULL pathname!\n"); dwLastError = ERROR_PATH_NOT_FOUND; goto done; } UnixPathName = PAL__strdup(lpPathName); if (UnixPathName == NULL ) { ERROR("PAL__strdup() failed\n"); dwLastError = ERROR_NOT_ENOUGH_MEMORY; goto done; } FILEDosToUnixPathA( UnixPathName ); // Remove any trailing slashes at the end because mkdir might not // handle them appropriately on all platforms. pathLength = strlen(UnixPathName); i = pathLength; while(i > 1) { if(UnixPathName[i - 1] =='/') { UnixPathName[i - 1]='\0'; i--; } else { break; } } // Check the constraint for the real path length (should be < MAX_LONGPATH). // Get an absolute path. if (UnixPathName[0] == '/') { realPath = UnixPathName; } else { const char *cwd = PAL__getcwd(NULL, MAX_LONGPATH); if (NULL == cwd) { WARN("Getcwd failed with errno=%d [%s]\n", errno, strerror(errno)); dwLastError = DIRGetLastErrorFromErrno(); goto done; } // Copy cwd, '/', path int iLen = strlen(cwd) + 1 + pathLength + 1; realPath = static_cast<char *>(alloca(iLen)); sprintf_s(realPath, iLen, "%s/%s", cwd, UnixPathName); PAL_free((char *)cwd); } // Canonicalize the path so we can determine its length. FILECanonicalizePath(realPath); if (strlen(realPath) >= MAX_LONGPATH) { WARN("UnixPathName is larger than MAX_LONGPATH (%d)!\n", MAX_LONGPATH); dwLastError = ERROR_FILENAME_EXCED_RANGE; goto done; } if ( mkdir(realPath, mode) != 0 ) { TRACE("Creation of directory [%s] was unsuccessful, errno = %d.\n", UnixPathName, errno); switch( errno ) { case ENOTDIR: /* FALL THROUGH */ case ENOENT: FILEGetProperNotFoundError( realPath, &dwLastError ); goto done; case EEXIST: dwLastError = ERROR_ALREADY_EXISTS; break; default: dwLastError = ERROR_ACCESS_DENIED; } } else { TRACE("Creation of directory [%s] was successful.\n", UnixPathName); bRet = TRUE; } done: if( dwLastError ) { SetLastError( dwLastError ); } PAL_free( UnixPathName ); LOGEXIT("CreateDirectoryA returns BOOL %d\n", bRet); PERF_EXIT(CreateDirectoryA); return bRet; }
/*++ Function: CreateDirectoryA Note: lpSecurityAttributes always NULL. See MSDN doc. --*/ BOOL PALAPI CreateDirectoryA( IN LPCSTR lpPathName, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes) { BOOL bRet = FALSE; DWORD dwLastError = 0; PathCharString realPath; char* realPathBuf; LPSTR unixPathName = NULL; int pathLength; int i; const int mode = S_IRWXU | S_IRWXG | S_IRWXO; PERF_ENTRY(CreateDirectoryA); ENTRY("CreateDirectoryA(lpPathName=%p (%s), lpSecurityAttr=%p)\n", lpPathName?lpPathName:"NULL", lpPathName?lpPathName:"NULL", lpSecurityAttributes); if ( lpSecurityAttributes ) { ASSERT("lpSecurityAttributes is not NULL as it should be\n"); dwLastError = ERROR_INVALID_PARAMETER; goto done; } // Windows returns ERROR_PATH_NOT_FOUND when called with NULL. // If we don't have this check, strdup(NULL) segfaults. if (lpPathName == NULL) { ERROR("CreateDirectoryA called with NULL pathname!\n"); dwLastError = ERROR_PATH_NOT_FOUND; goto done; } unixPathName = PAL__strdup(lpPathName); if (unixPathName == NULL ) { ERROR("PAL__strdup() failed\n"); dwLastError = ERROR_NOT_ENOUGH_MEMORY; goto done; } FILEDosToUnixPathA( unixPathName ); // Remove any trailing slashes at the end because mkdir might not // handle them appropriately on all platforms. pathLength = strlen(unixPathName); i = pathLength; while(i > 1) { if(unixPathName[i - 1] =='/') { unixPathName[i - 1]='\0'; i--; } else { break; } } // Get an absolute path. if (unixPathName[0] == '/') { realPathBuf = unixPathName; } else { DWORD len = GetCurrentDirectoryA(realPath); if (len == 0 || !realPath.Reserve(realPath.GetCount() + pathLength + 1 )) { dwLastError = DIRGetLastErrorFromErrno(); WARN("Getcwd failed with errno=%d \n", dwLastError); goto done; } realPath.Append("/", 1); realPath.Append(unixPathName, pathLength); realPathBuf = realPath.OpenStringBuffer(realPath.GetCount()); } // Canonicalize the path so we can determine its length. FILECanonicalizePath(realPathBuf); if ( mkdir(realPathBuf, mode) != 0 ) { TRACE("Creation of directory [%s] was unsuccessful, errno = %d.\n", unixPathName, errno); switch( errno ) { case ENOTDIR: /* FALL THROUGH */ case ENOENT: FILEGetProperNotFoundError( realPathBuf, &dwLastError ); goto done; case EEXIST: dwLastError = ERROR_ALREADY_EXISTS; break; default: dwLastError = ERROR_ACCESS_DENIED; } } else { TRACE("Creation of directory [%s] was successful.\n", unixPathName); bRet = TRUE; } realPath.CloseBuffer(0); //The PathCharString usage is done done: if( dwLastError ) { SetLastError( dwLastError ); } PAL_free( unixPathName ); LOGEXIT("CreateDirectoryA returns BOOL %d\n", bRet); PERF_EXIT(CreateDirectoryA); return bRet; }
__cdecl PAL_fopen(const char * fileName, const char * mode) { PAL_FILE *f = NULL; LPSTR supported = NULL; LPSTR UnixFileName = NULL; struct stat stat_data; BOOL bTextMode = TRUE; PERF_ENTRY(fopen); ENTRY("fopen ( fileName=%p (%s) mode=%p (%s))\n", fileName, fileName, mode , mode ); _ASSERTE(fileName != NULL); _ASSERTE(mode != NULL); if ( *mode == 'r' || *mode == 'w' || *mode == 'a' ) { supported = MapFileOpenModes( (char*)mode,&bTextMode); if ( !supported ) { goto done; } UnixFileName = PAL__strdup(fileName); if (UnixFileName == NULL ) { ERROR("PAL__strdup() failed\n"); SetLastError(ERROR_NOT_ENOUGH_MEMORY); goto done; } FILEDosToUnixPathA( UnixFileName ); /*I am not checking for the case where stat fails *as fopen will handle the error more gracefully in case *UnixFileName is invalid*/ if ((stat(UnixFileName, &stat_data) == 0 ) && ((stat_data.st_mode & S_IFMT) == S_IFDIR)) { goto done; } f = (PAL_FILE*)PAL_malloc( sizeof( PAL_FILE ) ); if ( f ) { f->bsdFilePtr = (FILE*)fopen( UnixFileName, supported ); f->PALferrorCode = PAL_FILE_NOERROR; f->bTextMode = bTextMode; if ( !f->bsdFilePtr ) { /* Failed */ PAL_free( f ); f = NULL; } #if UNGETC_NOT_RETURN_EOF else { f->bWriteOnlyMode = WriteOnlyMode(f->bsdFilePtr); } #endif //UNGETC_NOT_RETURN_EOF } else { ERROR( "Unable to allocate memory to the PAL_FILE wrapper\n" ); } } else { ERROR( "The mode flags must start with either an a, w, or r.\n" ); } done: PAL_free( supported ); supported = NULL; PAL_free( UnixFileName ); LOGEXIT( "fopen returns FILE* %p\n", f ); PERF_EXIT(fopen); return f; }
/*++ Function: MessageBoxW This is a small subset of MessageBox that simply logs a message to the system logging facility and returns. A typical log entry will look like: May 23 15:48:10 rice example1: MessageBox: Caption: Error Text Note: hWnd should always be NULL. See MSDN doc. --*/ int PALAPI MessageBoxW( IN LPVOID hWnd, IN LPCWSTR lpText, IN LPCWSTR lpCaption, IN UINT uType) { CHAR *text = NULL; CHAR *caption = NULL; INT len = 0; INT rc = 0; PERF_ENTRY(MessageBoxW); ENTRY( "MessageBoxW (hWnd=%p, lpText=%p (%S), lpCaption=%p (%S), uType=%#x)\n", hWnd, lpText?lpText:W16_NULLSTRING, lpText?lpText:W16_NULLSTRING, lpCaption?lpCaption:W16_NULLSTRING, lpCaption?lpCaption:W16_NULLSTRING, uType ); if (hWnd != NULL) { ASSERT("hWnd != NULL"); } if(lpText) { len = WideCharToMultiByte(CP_ACP, 0, lpText, -1, NULL, 0, NULL, NULL); if(len) { text = (LPSTR)PAL_malloc(len); if(!text) { ERROR("malloc() failed!\n"); SetLastError( ERROR_NOT_ENOUGH_MEMORY ); goto error; } if( !WideCharToMultiByte( CP_ACP, 0, lpText, -1, text, len, NULL, NULL)) { ASSERT("WideCharToMultiByte failure\n"); SetLastError( ERROR_INTERNAL_ERROR ); goto error; } } else { ASSERT("WideCharToMultiByte failure\n"); SetLastError( ERROR_INTERNAL_ERROR ); goto error; } } else { WARN("No message text\n"); if (NULL == (text = PAL__strdup("(no message text)"))) { ASSERT("strdup() failed\n"); SetLastError( ERROR_INTERNAL_ERROR ); goto error; } } if (lpCaption) { len = WideCharToMultiByte( CP_ACP, 0, lpCaption, -1, NULL, 0, NULL, NULL); if(len) { caption = (CHAR*)PAL_malloc(len); if(!caption) { ERROR("malloc() failed!\n"); SetLastError( ERROR_NOT_ENOUGH_MEMORY ); goto error; } if( !WideCharToMultiByte( CP_ACP, 0, lpCaption, -1, caption, len, NULL, NULL)) { ASSERT("WideCharToMultiByte failure\n"); SetLastError( ERROR_INTERNAL_ERROR ); goto error; } } else { ASSERT("WideCharToMultiByte failure\n"); SetLastError( ERROR_INTERNAL_ERROR ); goto error; } } else { if (NULL == (caption = PAL__strdup("Error"))) { ERROR("strdup() failed\n"); SetLastError( ERROR_NOT_ENOUGH_MEMORY ); goto error; } } rc = MessageBoxA(hWnd, text, caption, uType); error: PAL_free(caption); PAL_free(text); LOGEXIT("MessageBoxW returns %d\n", rc); PERF_EXIT(MessageBoxW); return rc; }
/*++ Function: GetFullPathNameA See MSDN doc. --*/ DWORD PALAPI GetFullPathNameA( IN LPCSTR lpFileName, IN DWORD nBufferLength, OUT LPSTR lpBuffer, OUT LPSTR *lpFilePart) { DWORD nReqPathLen, nRet = 0; LPSTR lpUnixPath = NULL; BOOL fullPath = FALSE; PERF_ENTRY(GetFullPathNameA); ENTRY("GetFullPathNameA(lpFileName=%p (%s), nBufferLength=%u, lpBuffer=%p, " "lpFilePart=%p)\n", lpFileName?lpFileName:"NULL", lpFileName?lpFileName:"NULL", nBufferLength, lpBuffer, lpFilePart); if(NULL == lpFileName) { WARN("lpFileName is NULL\n"); SetLastError(ERROR_INVALID_PARAMETER); goto done; } /* find out if lpFileName is a partial or full path */ if ('\\' == *lpFileName || '/' == *lpFileName) { fullPath = TRUE; } if(fullPath) { lpUnixPath = PAL__strdup( lpFileName ); if(NULL == lpUnixPath) { ERROR("strdup() failed; error is %d (%s)\n", errno, strerror(errno)); SetLastError(ERROR_NOT_ENOUGH_MEMORY); goto done; } } else { size_t max_len; /* allocate memory for full non-canonical path */ max_len = strlen(lpFileName)+1; /* 1 for the slash to append */ max_len += MAX_LONGPATH + 1; lpUnixPath = (LPSTR)PAL_malloc(max_len); if(NULL == lpUnixPath) { ERROR("PAL_malloc() failed; error is %d (%s)\n", errno, strerror(errno)); SetLastError(ERROR_NOT_ENOUGH_MEMORY); goto done; } /* build full path */ if(!GetCurrentDirectoryA(MAX_LONGPATH + 1, lpUnixPath)) { /* no reason for this to fail now... */ ASSERT("GetCurrentDirectoryA() failed! lasterror is %#xd\n", GetLastError()); SetLastError(ERROR_INTERNAL_ERROR); goto done; } if (strcat_s(lpUnixPath, max_len, "/") != SAFECRT_SUCCESS) { ERROR("strcat_s failed!\n"); SetLastError(ERROR_FILENAME_EXCED_RANGE); goto done; } if (strcat_s(lpUnixPath, max_len, lpFileName) != SAFECRT_SUCCESS) { ERROR("strcat_s failed!\n"); SetLastError(ERROR_FILENAME_EXCED_RANGE); goto done; } } /* do conversion to Unix path */ FILEDosToUnixPathA( lpUnixPath ); /* now we can canonicalize this */ FILECanonicalizePath(lpUnixPath); /* at last, we can figure out how long this path is */ nReqPathLen = strlen(lpUnixPath)+1; if(nBufferLength < nReqPathLen) { TRACE("reporting insufficient buffer : minimum is %d, caller " "provided %d\n", nReqPathLen, nBufferLength); nRet = nReqPathLen; goto done; } nRet = nReqPathLen-1; strcpy_s(lpBuffer, nBufferLength, lpUnixPath); /* locate the filename component if caller cares */ if(lpFilePart) { *lpFilePart = strrchr(lpBuffer, '/'); if (*lpFilePart == NULL) { ASSERT("Not able to find '/' in the full path.\n"); SetLastError( ERROR_INTERNAL_ERROR ); nRet = 0; goto done; } else { (*lpFilePart)++; } } done: PAL_free (lpUnixPath); LOGEXIT("GetFullPathNameA returns DWORD %u\n", nRet); PERF_EXIT(GetFullPathNameA); return nRet; }