123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539 |
- /**
- * WinPR: Windows Portable Runtime
- * File Functions
- *
- * Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
- * Copyright 2014 Hewlett-Packard Development Company, L.P.
- * Copyright 2016 David PHAM-VAN <d.phamvan@inuvika.com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- #ifdef HAVE_CONFIG_H
- #include "config.h"
- #endif
- #include <winpr/crt.h>
- #include <winpr/path.h>
- #include <winpr/file.h>
- #ifdef HAVE_UNISTD_H
- #include <unistd.h>
- #endif
- #ifdef HAVE_FCNTL_H
- #include <fcntl.h>
- #endif
- #include "../log.h"
- #define TAG WINPR_TAG("file")
- #ifdef _WIN32
- #include <io.h>
- #include <sys/stat.h>
- #else
- #include <assert.h>
- #include <pthread.h>
- #include <dirent.h>
- #include <libgen.h>
- #include <errno.h>
- #include <sys/un.h>
- #include <sys/stat.h>
- #include <sys/socket.h>
- #ifdef HAVE_AIO_H
- #undef HAVE_AIO_H /* disable for now, incomplete */
- #endif
- #ifdef HAVE_AIO_H
- #include <aio.h>
- #endif
- #ifdef ANDROID
- #include <sys/vfs.h>
- #include <winpr/timezone.h>
- #else
- #include <sys/statvfs.h>
- #endif
- #include "../handle/handle.h"
- #include "../pipe/pipe.h"
- #include "file.h"
- #include <winpr/timezone.h>
- /**
- * api-ms-win-core-file-l1-2-0.dll:
- *
- * CreateFileA
- * CreateFileW
- * CreateFile2
- * DeleteFileA
- * DeleteFileW
- * CreateDirectoryA
- * CreateDirectoryW
- * RemoveDirectoryA
- * RemoveDirectoryW
- * CompareFileTime
- * DefineDosDeviceW
- * DeleteVolumeMountPointW
- * FileTimeToLocalFileTime
- * LocalFileTimeToFileTime
- * FindClose
- * FindCloseChangeNotification
- * FindFirstChangeNotificationA
- * FindFirstChangeNotificationW
- * FindFirstFileA
- * FindFirstFileExA
- * FindFirstFileExW
- * FindFirstFileW
- * FindFirstVolumeW
- * FindNextChangeNotification
- * FindNextFileA
- * FindNextFileW
- * FindNextVolumeW
- * FindVolumeClose
- * GetDiskFreeSpaceA
- * GetDiskFreeSpaceExA
- * GetDiskFreeSpaceExW
- * GetDiskFreeSpaceW
- * GetDriveTypeA
- * GetDriveTypeW
- * GetFileAttributesA
- * GetFileAttributesExA
- * GetFileAttributesExW
- * GetFileAttributesW
- * GetFileInformationByHandle
- * GetFileSize
- * GetFileSizeEx
- * GetFileTime
- * GetFileType
- * GetFinalPathNameByHandleA
- * GetFinalPathNameByHandleW
- * GetFullPathNameA
- * GetFullPathNameW
- * GetLogicalDrives
- * GetLogicalDriveStringsW
- * GetLongPathNameA
- * GetLongPathNameW
- * GetShortPathNameW
- * GetTempFileNameW
- * GetTempPathW
- * GetVolumeInformationByHandleW
- * GetVolumeInformationW
- * GetVolumeNameForVolumeMountPointW
- * GetVolumePathNamesForVolumeNameW
- * GetVolumePathNameW
- * QueryDosDeviceW
- * SetFileAttributesA
- * SetFileAttributesW
- * SetFileTime
- * SetFileValidData
- * SetFileInformationByHandle
- * ReadFile
- * ReadFileEx
- * ReadFileScatter
- * WriteFile
- * WriteFileEx
- * WriteFileGather
- * FlushFileBuffers
- * SetEndOfFile
- * SetFilePointer
- * SetFilePointerEx
- * LockFile
- * LockFileEx
- * UnlockFile
- * UnlockFileEx
- */
- /**
- * File System Behavior in the Microsoft Windows Environment:
- * http://download.microsoft.com/download/4/3/8/43889780-8d45-4b2e-9d3a-c696a890309f/File%20System%20Behavior%20Overview.pdf
- */
- /**
- * Asynchronous I/O - The GNU C Library:
- * http://www.gnu.org/software/libc/manual/html_node/Asynchronous-I_002fO.html
- */
- /**
- * aio.h - asynchronous input and output:
- * http://pubs.opengroup.org/onlinepubs/009695399/basedefs/aio.h.html
- */
- /**
- * Asynchronous I/O User Guide:
- * http://code.google.com/p/kernel/wiki/AIOUserGuide
- */
- #define EPOCH_DIFF 11644473600LL
- #define STAT_TIME_TO_FILETIME(_t) (((UINT64)(_t) + EPOCH_DIFF) * 10000000LL)
- static wArrayList* _HandleCreators;
- static pthread_once_t _HandleCreatorsInitialized = PTHREAD_ONCE_INIT;
- extern HANDLE_CREATOR* GetNamedPipeClientHandleCreator(void);
- #if defined __linux__ && !defined ANDROID
- extern HANDLE_CREATOR* GetCommHandleCreator(void);
- #endif /* __linux__ && !defined ANDROID */
- static void _HandleCreatorsInit()
- {
- assert(_HandleCreators == NULL);
- _HandleCreators = ArrayList_New(TRUE);
- if (!_HandleCreators)
- return;
- /*
- * Register all file handle creators.
- */
- ArrayList_Add(_HandleCreators, GetNamedPipeClientHandleCreator());
- #if defined __linux__ && !defined ANDROID
- ArrayList_Add(_HandleCreators, GetCommHandleCreator());
- #endif /* __linux__ && !defined ANDROID */
- ArrayList_Add(_HandleCreators, GetFileHandleCreator());
- }
- #ifdef HAVE_AIO_H
- static BOOL g_AioSignalHandlerInstalled = FALSE;
- void AioSignalHandler(int signum, siginfo_t* siginfo, void* arg)
- {
- WLog_INFO("%d", signum);
- }
- int InstallAioSignalHandler()
- {
- if (!g_AioSignalHandlerInstalled)
- {
- struct sigaction action;
- sigemptyset(&action.sa_mask);
- sigaddset(&action.sa_mask, SIGIO);
- action.sa_flags = SA_SIGINFO;
- action.sa_sigaction = (void*)&AioSignalHandler;
- sigaction(SIGIO, &action, NULL);
- g_AioSignalHandlerInstalled = TRUE;
- }
- return 0;
- }
- #endif /* HAVE_AIO_H */
- HANDLE CreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode,
- LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition,
- DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
- {
- int i;
- if (!lpFileName)
- return INVALID_HANDLE_VALUE;
- if (pthread_once(&_HandleCreatorsInitialized, _HandleCreatorsInit) != 0)
- {
- SetLastError(ERROR_DLL_INIT_FAILED);
- return INVALID_HANDLE_VALUE;
- }
- if (_HandleCreators == NULL)
- {
- SetLastError(ERROR_DLL_INIT_FAILED);
- return INVALID_HANDLE_VALUE;
- }
- ArrayList_Lock(_HandleCreators);
- for (i = 0; i <= ArrayList_Count(_HandleCreators); i++)
- {
- HANDLE_CREATOR* creator = ArrayList_GetItem(_HandleCreators, i);
- if (creator && creator->IsHandled(lpFileName))
- {
- HANDLE newHandle =
- creator->CreateFileA(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes,
- dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
- ArrayList_Unlock(_HandleCreators);
- return newHandle;
- }
- }
- ArrayList_Unlock(_HandleCreators);
- return INVALID_HANDLE_VALUE;
- }
- HANDLE CreateFileW(LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode,
- LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition,
- DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
- {
- LPSTR lpFileNameA = NULL;
- HANDLE hdl;
- if (ConvertFromUnicode(CP_UTF8, 0, lpFileName, -1, &lpFileNameA, 0, NULL, NULL) < 1)
- return NULL;
- hdl = CreateFileA(lpFileNameA, dwDesiredAccess, dwShareMode, lpSecurityAttributes,
- dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
- free(lpFileNameA);
- return hdl;
- }
- BOOL DeleteFileA(LPCSTR lpFileName)
- {
- int status;
- status = unlink(lpFileName);
- return (status != -1) ? TRUE : FALSE;
- }
- BOOL DeleteFileW(LPCWSTR lpFileName)
- {
- LPSTR lpFileNameA = NULL;
- BOOL rc = FALSE;
- if (ConvertFromUnicode(CP_UTF8, 0, lpFileName, -1, &lpFileNameA, 0, NULL, NULL) < 1)
- return FALSE;
- rc = DeleteFileA(lpFileNameA);
- free(lpFileNameA);
- return rc;
- }
- BOOL ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
- LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped)
- {
- ULONG Type;
- WINPR_HANDLE* handle;
- if (hFile == INVALID_HANDLE_VALUE)
- return FALSE;
- /*
- * from http://msdn.microsoft.com/en-us/library/windows/desktop/aa365467%28v=vs.85%29.aspx
- * lpNumberOfBytesRead can be NULL only when the lpOverlapped parameter is not NULL.
- */
- if (!lpNumberOfBytesRead && !lpOverlapped)
- return FALSE;
- if (!winpr_Handle_GetInfo(hFile, &Type, &handle))
- return FALSE;
- handle = (WINPR_HANDLE*)hFile;
- if (handle->ops->ReadFile)
- return handle->ops->ReadFile(handle, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead,
- lpOverlapped);
- WLog_ERR(TAG, "ReadFile operation not implemented");
- return FALSE;
- }
- BOOL ReadFileEx(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
- LPOVERLAPPED lpOverlapped, LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
- {
- ULONG Type;
- WINPR_HANDLE* handle;
- if (hFile == INVALID_HANDLE_VALUE)
- return FALSE;
- if (!winpr_Handle_GetInfo(hFile, &Type, &handle))
- return FALSE;
- handle = (WINPR_HANDLE*)hFile;
- if (handle->ops->ReadFileEx)
- return handle->ops->ReadFileEx(handle, lpBuffer, nNumberOfBytesToRead, lpOverlapped,
- lpCompletionRoutine);
- WLog_ERR(TAG, "ReadFileEx operation not implemented");
- return FALSE;
- return TRUE;
- }
- BOOL ReadFileScatter(HANDLE hFile, FILE_SEGMENT_ELEMENT aSegmentArray[], DWORD nNumberOfBytesToRead,
- LPDWORD lpReserved, LPOVERLAPPED lpOverlapped)
- {
- ULONG Type;
- WINPR_HANDLE* handle;
- if (hFile == INVALID_HANDLE_VALUE)
- return FALSE;
- if (!winpr_Handle_GetInfo(hFile, &Type, &handle))
- return FALSE;
- handle = (WINPR_HANDLE*)hFile;
- if (handle->ops->ReadFileScatter)
- return handle->ops->ReadFileScatter(handle, aSegmentArray, nNumberOfBytesToRead, lpReserved,
- lpOverlapped);
- WLog_ERR(TAG, "ReadFileScatter operation not implemented");
- return FALSE;
- }
- BOOL WriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,
- LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped)
- {
- ULONG Type;
- WINPR_HANDLE* handle;
- if (hFile == INVALID_HANDLE_VALUE)
- return FALSE;
- if (!winpr_Handle_GetInfo(hFile, &Type, &handle))
- return FALSE;
- handle = (WINPR_HANDLE*)hFile;
- if (handle->ops->WriteFile)
- return handle->ops->WriteFile(handle, lpBuffer, nNumberOfBytesToWrite,
- lpNumberOfBytesWritten, lpOverlapped);
- WLog_ERR(TAG, "WriteFile operation not implemented");
- return FALSE;
- }
- BOOL WriteFileEx(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,
- LPOVERLAPPED lpOverlapped, LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
- {
- ULONG Type;
- WINPR_HANDLE* handle;
- if (hFile == INVALID_HANDLE_VALUE)
- return FALSE;
- if (!winpr_Handle_GetInfo(hFile, &Type, &handle))
- return FALSE;
- handle = (WINPR_HANDLE*)hFile;
- if (handle->ops->WriteFileEx)
- return handle->ops->WriteFileEx(handle, lpBuffer, nNumberOfBytesToWrite, lpOverlapped,
- lpCompletionRoutine);
- WLog_ERR(TAG, "WriteFileEx operation not implemented");
- return FALSE;
- }
- BOOL WriteFileGather(HANDLE hFile, FILE_SEGMENT_ELEMENT aSegmentArray[],
- DWORD nNumberOfBytesToWrite, LPDWORD lpReserved, LPOVERLAPPED lpOverlapped)
- {
- ULONG Type;
- WINPR_HANDLE* handle;
- if (hFile == INVALID_HANDLE_VALUE)
- return FALSE;
- if (!winpr_Handle_GetInfo(hFile, &Type, &handle))
- return FALSE;
- handle = (WINPR_HANDLE*)hFile;
- if (handle->ops->WriteFileGather)
- return handle->ops->WriteFileGather(handle, aSegmentArray, nNumberOfBytesToWrite,
- lpReserved, lpOverlapped);
- WLog_ERR(TAG, "WriteFileGather operation not implemented");
- return FALSE;
- }
- BOOL FlushFileBuffers(HANDLE hFile)
- {
- ULONG Type;
- WINPR_HANDLE* handle;
- if (hFile == INVALID_HANDLE_VALUE)
- return FALSE;
- if (!winpr_Handle_GetInfo(hFile, &Type, &handle))
- return FALSE;
- handle = (WINPR_HANDLE*)hFile;
- if (handle->ops->FlushFileBuffers)
- return handle->ops->FlushFileBuffers(handle);
- WLog_ERR(TAG, "FlushFileBuffers operation not implemented");
- return FALSE;
- }
- BOOL WINAPI GetFileAttributesExA(LPCSTR lpFileName, GET_FILEEX_INFO_LEVELS fInfoLevelId,
- LPVOID lpFileInformation)
- {
- LPWIN32_FILE_ATTRIBUTE_DATA fd = lpFileInformation;
- WIN32_FIND_DATAA findFileData;
- HANDLE hFind;
- if (!fd)
- return FALSE;
- if ((hFind = FindFirstFileA(lpFileName, &findFileData)) == INVALID_HANDLE_VALUE)
- return FALSE;
- FindClose(hFind);
- fd->dwFileAttributes = findFileData.dwFileAttributes;
- fd->ftCreationTime = findFileData.ftCreationTime;
- fd->ftLastAccessTime = findFileData.ftLastAccessTime;
- fd->ftLastWriteTime = findFileData.ftLastWriteTime;
- fd->nFileSizeHigh = findFileData.nFileSizeHigh;
- fd->nFileSizeLow = findFileData.nFileSizeLow;
- return TRUE;
- }
- BOOL WINAPI GetFileAttributesExW(LPCWSTR lpFileName, GET_FILEEX_INFO_LEVELS fInfoLevelId,
- LPVOID lpFileInformation)
- {
- BOOL ret;
- LPSTR lpCFileName;
- if (ConvertFromUnicode(CP_UTF8, 0, lpFileName, -1, &lpCFileName, 0, NULL, NULL) <= 0)
- {
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- return FALSE;
- }
- ret = GetFileAttributesExA(lpCFileName, fInfoLevelId, lpFileInformation);
- free(lpCFileName);
- return ret;
- }
- DWORD WINAPI GetFileAttributesA(LPCSTR lpFileName)
- {
- WIN32_FIND_DATAA findFileData;
- HANDLE hFind;
- if ((hFind = FindFirstFileA(lpFileName, &findFileData)) == INVALID_HANDLE_VALUE)
- return INVALID_FILE_ATTRIBUTES;
- FindClose(hFind);
- return findFileData.dwFileAttributes;
- }
- DWORD WINAPI GetFileAttributesW(LPCWSTR lpFileName)
- {
- DWORD ret;
- LPSTR lpCFileName;
- if (ConvertFromUnicode(CP_UTF8, 0, lpFileName, -1, &lpCFileName, 0, NULL, NULL) <= 0)
- {
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- return FALSE;
- }
- ret = GetFileAttributesA(lpCFileName);
- free(lpCFileName);
- return ret;
- }
- BOOL SetFileAttributesA(LPCSTR lpFileName, DWORD dwFileAttributes)
- {
- struct stat st;
- if (stat(lpFileName, &st) != 0)
- {
- return FALSE;
- }
- if (dwFileAttributes & FILE_ATTRIBUTE_READONLY)
- {
- st.st_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
- }
- else
- {
- st.st_mode |= S_IWUSR;
- }
- if (chmod(lpFileName, st.st_mode) != 0)
- {
- return FALSE;
- }
- return TRUE;
- }
- BOOL SetFileAttributesW(LPCWSTR lpFileName, DWORD dwFileAttributes)
- {
- BOOL ret;
- LPSTR lpCFileName;
- if (ConvertFromUnicode(CP_UTF8, 0, lpFileName, -1, &lpCFileName, 0, NULL, NULL) <= 0)
- {
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- return FALSE;
- }
- ret = SetFileAttributesA(lpCFileName, dwFileAttributes);
- free(lpCFileName);
- return ret;
- }
- BOOL SetEndOfFile(HANDLE hFile)
- {
- ULONG Type;
- WINPR_HANDLE* handle;
- if (hFile == INVALID_HANDLE_VALUE)
- return FALSE;
- if (!winpr_Handle_GetInfo(hFile, &Type, &handle))
- return FALSE;
- handle = (WINPR_HANDLE*)hFile;
- if (handle->ops->SetEndOfFile)
- return handle->ops->SetEndOfFile(handle);
- WLog_ERR(TAG, "SetEndOfFile operation not implemented");
- return FALSE;
- }
- DWORD WINAPI GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh)
- {
- ULONG Type;
- WINPR_HANDLE* handle;
- if (hFile == INVALID_HANDLE_VALUE)
- return FALSE;
- if (!winpr_Handle_GetInfo(hFile, &Type, &handle))
- return FALSE;
- handle = (WINPR_HANDLE*)hFile;
- if (handle->ops->GetFileSize)
- return handle->ops->GetFileSize(handle, lpFileSizeHigh);
- WLog_ERR(TAG, "GetFileSize operation not implemented");
- return 0;
- }
- BOOL GetFileTime(HANDLE hFile, LPFILETIME lpCreationTime, LPFILETIME lpLastAccessTime, LPFILETIME lpLastWriteTime)
- {
- ULONG Type;
- WINPR_HANDLE* handle;
- if(hFile == INVALID_HANDLE_VALUE) {
- return FALSE;
- }
- if(!winpr_Handle_GetInfo(hFile, &Type, &handle)) {
- return FALSE;
- }
- handle = (WINPR_HANDLE*)hFile;
- if(handle->ops->GetFileTime)
- return handle->ops->GetFileTime(handle, lpCreationTime, lpLastAccessTime, lpLastWriteTime);
- WLog_ERR(TAG, "GetFileTime operation not implemented");
- return FALSE;
- }
- DWORD SetFilePointer(HANDLE hFile, LONG lDistanceToMove, PLONG lpDistanceToMoveHigh,
- DWORD dwMoveMethod)
- {
- ULONG Type;
- WINPR_HANDLE* handle;
- if (hFile == INVALID_HANDLE_VALUE)
- return FALSE;
- if (!winpr_Handle_GetInfo(hFile, &Type, &handle))
- return FALSE;
- handle = (WINPR_HANDLE*)hFile;
- if (handle->ops->SetFilePointer)
- return handle->ops->SetFilePointer(handle, lDistanceToMove, lpDistanceToMoveHigh,
- dwMoveMethod);
- WLog_ERR(TAG, "SetFilePointer operation not implemented");
- return 0;
- }
- BOOL SetFilePointerEx(HANDLE hFile, LARGE_INTEGER liDistanceToMove, PLARGE_INTEGER lpNewFilePointer,
- DWORD dwMoveMethod)
- {
- ULONG Type;
- WINPR_HANDLE* handle;
- if (hFile == INVALID_HANDLE_VALUE)
- return FALSE;
- if (!winpr_Handle_GetInfo(hFile, &Type, &handle))
- return FALSE;
- handle = (WINPR_HANDLE*)hFile;
- if (handle->ops->SetFilePointerEx)
- return handle->ops->SetFilePointerEx(handle, liDistanceToMove, lpNewFilePointer,
- dwMoveMethod);
- WLog_ERR(TAG, "SetFilePointerEx operation not implemented");
- return 0;
- }
- BOOL LockFile(HANDLE hFile, DWORD dwFileOffsetLow, DWORD dwFileOffsetHigh,
- DWORD nNumberOfBytesToLockLow, DWORD nNumberOfBytesToLockHigh)
- {
- ULONG Type;
- WINPR_HANDLE* handle;
- if (hFile == INVALID_HANDLE_VALUE)
- return FALSE;
- if (!winpr_Handle_GetInfo(hFile, &Type, &handle))
- return FALSE;
- handle = (WINPR_HANDLE*)hFile;
- if (handle->ops->LockFile)
- return handle->ops->LockFile(handle, dwFileOffsetLow, dwFileOffsetHigh,
- nNumberOfBytesToLockLow, nNumberOfBytesToLockHigh);
- WLog_ERR(TAG, "LockFile operation not implemented");
- return FALSE;
- }
- BOOL LockFileEx(HANDLE hFile, DWORD dwFlags, DWORD dwReserved, DWORD nNumberOfBytesToLockLow,
- DWORD nNumberOfBytesToLockHigh, LPOVERLAPPED lpOverlapped)
- {
- ULONG Type;
- WINPR_HANDLE* handle;
- if (hFile == INVALID_HANDLE_VALUE)
- return FALSE;
- if (!winpr_Handle_GetInfo(hFile, &Type, &handle))
- return FALSE;
- handle = (WINPR_HANDLE*)hFile;
- if (handle->ops->LockFileEx)
- return handle->ops->LockFileEx(handle, dwFlags, dwReserved, nNumberOfBytesToLockLow,
- nNumberOfBytesToLockHigh, lpOverlapped);
- WLog_ERR(TAG, "LockFileEx operation not implemented");
- return FALSE;
- }
- BOOL UnlockFile(HANDLE hFile, DWORD dwFileOffsetLow, DWORD dwFileOffsetHigh,
- DWORD nNumberOfBytesToUnlockLow, DWORD nNumberOfBytesToUnlockHigh)
- {
- ULONG Type;
- WINPR_HANDLE* handle;
- if (hFile == INVALID_HANDLE_VALUE)
- return FALSE;
- if (!winpr_Handle_GetInfo(hFile, &Type, &handle))
- return FALSE;
- handle = (WINPR_HANDLE*)hFile;
- if (handle->ops->UnlockFile)
- return handle->ops->UnlockFile(handle, dwFileOffsetLow, dwFileOffsetHigh,
- nNumberOfBytesToUnlockLow, nNumberOfBytesToUnlockHigh);
- WLog_ERR(TAG, "UnLockFile operation not implemented");
- return FALSE;
- }
- BOOL UnlockFileEx(HANDLE hFile, DWORD dwReserved, DWORD nNumberOfBytesToUnlockLow,
- DWORD nNumberOfBytesToUnlockHigh, LPOVERLAPPED lpOverlapped)
- {
- ULONG Type;
- WINPR_HANDLE* handle;
- if (hFile == INVALID_HANDLE_VALUE)
- return FALSE;
- if (!winpr_Handle_GetInfo(hFile, &Type, &handle))
- return FALSE;
- handle = (WINPR_HANDLE*)hFile;
- if (handle->ops->UnlockFileEx)
- return handle->ops->UnlockFileEx(handle, dwReserved, nNumberOfBytesToUnlockLow,
- nNumberOfBytesToUnlockHigh, lpOverlapped);
- WLog_ERR(TAG, "UnLockFileEx operation not implemented");
- return FALSE;
- }
- BOOL WINAPI SetFileTime(HANDLE hFile, const FILETIME* lpCreationTime,
- const FILETIME* lpLastAccessTime, const FILETIME* lpLastWriteTime)
- {
- ULONG Type;
- WINPR_HANDLE* handle;
- if (hFile == INVALID_HANDLE_VALUE)
- return FALSE;
- if (!winpr_Handle_GetInfo(hFile, &Type, &handle))
- return FALSE;
- handle = (WINPR_HANDLE*)hFile;
- if (handle->ops->SetFileTime)
- return handle->ops->SetFileTime(handle, lpCreationTime, lpLastAccessTime, lpLastWriteTime);
- WLog_ERR(TAG, "%s operation not implemented", __FUNCTION__);
- return FALSE;
- }
- struct _WIN32_FILE_SEARCH
- {
- DIR* pDir;
- LPSTR lpPath;
- LPSTR lpPattern;
- struct dirent* pDirent;
- };
- typedef struct _WIN32_FILE_SEARCH WIN32_FILE_SEARCH;
- static BOOL FindDataFromStat(const char* path, const struct stat* fileStat,
- LPWIN32_FIND_DATAA lpFindFileData)
- {
- UINT64 ft;
- char* lastSep;
- lpFindFileData->dwFileAttributes = 0;
- if (S_ISDIR(fileStat->st_mode))
- lpFindFileData->dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY;
- if (lpFindFileData->dwFileAttributes == 0)
- lpFindFileData->dwFileAttributes = FILE_ATTRIBUTE_ARCHIVE;
- lastSep = strrchr(path, '/');
- if (lastSep)
- {
- const char* name = lastSep + 1;
- const size_t namelen = strlen(name);
- if ((namelen > 1) && (name[0] == '.') && (name[1] != '.'))
- lpFindFileData->dwFileAttributes |= FILE_ATTRIBUTE_HIDDEN;
- }
- if (!(fileStat->st_mode & S_IWUSR))
- lpFindFileData->dwFileAttributes |= FILE_ATTRIBUTE_READONLY;
- #ifdef _DARWIN_FEATURE_64_BIT_INODE
- ft = STAT_TIME_TO_FILETIME(fileStat->st_birthtime);
- #else
- ft = STAT_TIME_TO_FILETIME(fileStat->st_ctime);
- #endif
- lpFindFileData->ftCreationTime.dwHighDateTime = ((UINT64)ft) >> 32ULL;
- lpFindFileData->ftCreationTime.dwLowDateTime = ft & 0xFFFFFFFF;
- ft = STAT_TIME_TO_FILETIME(fileStat->st_mtime);
- lpFindFileData->ftLastWriteTime.dwHighDateTime = ((UINT64)ft) >> 32ULL;
- lpFindFileData->ftLastWriteTime.dwLowDateTime = ft & 0xFFFFFFFF;
- ft = STAT_TIME_TO_FILETIME(fileStat->st_atime);
- lpFindFileData->ftLastAccessTime.dwHighDateTime = ((UINT64)ft) >> 32ULL;
- lpFindFileData->ftLastAccessTime.dwLowDateTime = ft & 0xFFFFFFFF;
- lpFindFileData->nFileSizeHigh = ((UINT64)fileStat->st_size) >> 32ULL;
- lpFindFileData->nFileSizeLow = fileStat->st_size & 0xFFFFFFFF;
- return TRUE;
- }
- HANDLE FindFirstFileA(LPCSTR lpFileName, LPWIN32_FIND_DATAA lpFindFileData)
- {
- BOOL isDir = FALSE;
- struct stat fileStat;
- WIN32_FILE_SEARCH* pFileSearch;
- if (!lpFindFileData || !lpFileName)
- {
- SetLastError(ERROR_BAD_ARGUMENTS);
- return INVALID_HANDLE_VALUE;
- }
- ZeroMemory(lpFindFileData, sizeof(WIN32_FIND_DATAA));
- pFileSearch = (WIN32_FILE_SEARCH*)calloc(1, sizeof(WIN32_FILE_SEARCH));
- if (!pFileSearch)
- {
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- return INVALID_HANDLE_VALUE;
- }
- if (stat(lpFileName, &fileStat) >= 0)
- {
- isDir = (S_ISDIR(fileStat.st_mode) != 0);
- }
- else
- errno = 0;
- if (isDir)
- {
- pFileSearch->lpPath = _strdup(lpFileName);
- pFileSearch->lpPattern = _strdup(".");
- }
- else
- {
- LPSTR p;
- size_t index;
- size_t length;
- /* Separate lpFileName into path and pattern components */
- p = strrchr(lpFileName, '/');
- if (!p)
- p = strrchr(lpFileName, '\\');
- index = (p - lpFileName);
- length = (p - lpFileName) + 1;
- pFileSearch->lpPath = (LPSTR)malloc(length + 1);
- if (!pFileSearch->lpPath)
- {
- free(pFileSearch);
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- return INVALID_HANDLE_VALUE;
- }
- CopyMemory(pFileSearch->lpPath, lpFileName, length);
- pFileSearch->lpPath[length] = '\0';
- length = strlen(lpFileName) - index;
- pFileSearch->lpPattern = (LPSTR)malloc(length + 1);
- if (!pFileSearch->lpPattern)
- {
- free(pFileSearch->lpPath);
- free(pFileSearch);
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- return INVALID_HANDLE_VALUE;
- }
- CopyMemory(pFileSearch->lpPattern, &lpFileName[index + 1], length);
- pFileSearch->lpPattern[length] = '\0';
- /* Check if the path is a directory */
- if (stat(pFileSearch->lpPath, &fileStat) < 0)
- {
- FindClose(pFileSearch);
- SetLastError(map_posix_err(errno));
- errno = 0;
- return INVALID_HANDLE_VALUE; /* stat error */
- }
- if (S_ISDIR(fileStat.st_mode) == 0)
- {
- FindClose(pFileSearch);
- return INVALID_HANDLE_VALUE; /* not a directory */
- }
- }
- /* Open directory for reading */
- pFileSearch->pDir = opendir(pFileSearch->lpPath);
- if (!pFileSearch->pDir)
- {
- FindClose(pFileSearch);
- SetLastError(map_posix_err(errno));
- errno = 0;
- return INVALID_HANDLE_VALUE; /* failed to open directory */
- }
- if (FindNextFileA((HANDLE)pFileSearch, lpFindFileData))
- {
- if (isDir)
- {
- const char* name = strrchr(lpFileName, '/');
- if (!name)
- name = lpFileName;
- else
- name++;
- pFileSearch->lpPattern[0] = '*';
- sprintf_s(lpFindFileData->cFileName, ARRAYSIZE(lpFindFileData->cFileName), "%s", name);
- }
- return (HANDLE)pFileSearch;
- }
- FindClose(pFileSearch);
- return INVALID_HANDLE_VALUE;
- }
- static BOOL ConvertFindDataAToW(LPWIN32_FIND_DATAA lpFindFileDataA,
- LPWIN32_FIND_DATAW lpFindFileDataW)
- {
- size_t length;
- WCHAR* unicodeFileName;
- if (!lpFindFileDataA || !lpFindFileDataW)
- return FALSE;
- lpFindFileDataW->dwFileAttributes = lpFindFileDataA->dwFileAttributes;
- lpFindFileDataW->ftCreationTime = lpFindFileDataA->ftCreationTime;
- lpFindFileDataW->ftLastAccessTime = lpFindFileDataA->ftLastAccessTime;
- lpFindFileDataW->ftLastWriteTime = lpFindFileDataA->ftLastWriteTime;
- lpFindFileDataW->nFileSizeHigh = lpFindFileDataA->nFileSizeHigh;
- lpFindFileDataW->nFileSizeLow = lpFindFileDataA->nFileSizeLow;
- lpFindFileDataW->dwReserved0 = lpFindFileDataA->dwReserved0;
- lpFindFileDataW->dwReserved1 = lpFindFileDataA->dwReserved1;
- unicodeFileName = NULL;
- length = ConvertToUnicode(CP_UTF8, 0, lpFindFileDataA->cFileName, -1, &unicodeFileName, 0);
- if (length == 0)
- return FALSE;
- if (length > MAX_PATH)
- length = MAX_PATH;
- CopyMemory(lpFindFileDataW->cFileName, unicodeFileName, length * sizeof(WCHAR));
- free(unicodeFileName);
- length =
- ConvertToUnicode(CP_UTF8, 0, lpFindFileDataA->cAlternateFileName, -1, &unicodeFileName, 0);
- if (length == 0)
- return TRUE;
- if (length > 14)
- length = 14;
- CopyMemory(lpFindFileDataW->cAlternateFileName, unicodeFileName, length * sizeof(WCHAR));
- free(unicodeFileName);
- return TRUE;
- }
- HANDLE FindFirstFileW(LPCWSTR lpFileName, LPWIN32_FIND_DATAW lpFindFileData)
- {
- LPSTR utfFileName = NULL;
- HANDLE h;
- LPWIN32_FIND_DATAA fd = (LPWIN32_FIND_DATAA)calloc(1, sizeof(WIN32_FIND_DATAA));
- if (!fd)
- {
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- return INVALID_HANDLE_VALUE;
- }
- if (ConvertFromUnicode(CP_UTF8, 0, lpFileName, -1, &utfFileName, 0, NULL, NULL) <= 0)
- {
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- free(fd);
- return INVALID_HANDLE_VALUE;
- }
- h = FindFirstFileA(utfFileName, fd);
- free(utfFileName);
- if (h != INVALID_HANDLE_VALUE)
- {
- if (!ConvertFindDataAToW(fd, lpFindFileData))
- {
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- FindClose(h);
- h = INVALID_HANDLE_VALUE;
- goto out;
- }
- }
- out:
- free(fd);
- return h;
- }
- HANDLE FindFirstFileExA(LPCSTR lpFileName, FINDEX_INFO_LEVELS fInfoLevelId, LPVOID lpFindFileData,
- FINDEX_SEARCH_OPS fSearchOp, LPVOID lpSearchFilter, DWORD dwAdditionalFlags)
- {
- return INVALID_HANDLE_VALUE;
- }
- HANDLE FindFirstFileExW(LPCWSTR lpFileName, FINDEX_INFO_LEVELS fInfoLevelId, LPVOID lpFindFileData,
- FINDEX_SEARCH_OPS fSearchOp, LPVOID lpSearchFilter, DWORD dwAdditionalFlags)
- {
- return INVALID_HANDLE_VALUE;
- }
- BOOL FindNextFileA(HANDLE hFindFile, LPWIN32_FIND_DATAA lpFindFileData)
- {
- WIN32_FILE_SEARCH* pFileSearch;
- struct stat fileStat;
- char* fullpath;
- size_t pathlen;
- size_t namelen;
- if (!hFindFile || !lpFindFileData)
- return FALSE;
- if (hFindFile == INVALID_HANDLE_VALUE)
- return FALSE;
- ZeroMemory(lpFindFileData, sizeof(WIN32_FIND_DATAA));
- pFileSearch = (WIN32_FILE_SEARCH*)hFindFile;
- while ((pFileSearch->pDirent = readdir(pFileSearch->pDir)) != NULL)
- {
- if (FilePatternMatchA(pFileSearch->pDirent->d_name, pFileSearch->lpPattern))
- {
- BOOL success;
- strncpy(lpFindFileData->cFileName, pFileSearch->pDirent->d_name, MAX_PATH);
- namelen = strnlen(lpFindFileData->cFileName, MAX_PATH);
- pathlen = strlen(pFileSearch->lpPath);
- fullpath = (char*)malloc(pathlen + namelen + 2);
- if (fullpath == NULL)
- {
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- return FALSE;
- }
- memcpy(fullpath, pFileSearch->lpPath, pathlen);
- /* Ensure path is terminated with a separator, but prevent
- * duplicate separators */
- if (fullpath[pathlen - 1] != '/')
- fullpath[pathlen++] = '/';
- memcpy(fullpath + pathlen, pFileSearch->pDirent->d_name, namelen);
- fullpath[pathlen + namelen] = 0;
- if (stat(fullpath, &fileStat) != 0)
- {
- free(fullpath);
- SetLastError(map_posix_err(errno));
- errno = 0;
- continue;
- }
- /* Skip FIFO entries. */
- if (S_ISFIFO(fileStat.st_mode))
- {
- free(fullpath);
- continue;
- }
- success = FindDataFromStat(fullpath, &fileStat, lpFindFileData);
- free(fullpath);
- return success;
- }
- }
- SetLastError(ERROR_NO_MORE_FILES);
- return FALSE;
- }
- BOOL FindNextFileW(HANDLE hFindFile, LPWIN32_FIND_DATAW lpFindFileData)
- {
- LPWIN32_FIND_DATAA fd = (LPWIN32_FIND_DATAA)calloc(1, sizeof(WIN32_FIND_DATAA));
- if (!fd)
- {
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- return FALSE;
- }
- if (FindNextFileA(hFindFile, fd))
- {
- if (!ConvertFindDataAToW(fd, lpFindFileData))
- {
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- free(fd);
- return FALSE;
- }
- free(fd);
- return TRUE;
- }
- free(fd);
- return FALSE;
- }
- BOOL FindClose(HANDLE hFindFile)
- {
- WIN32_FILE_SEARCH* pFileSearch = (WIN32_FILE_SEARCH*)hFindFile;
- /* Since INVALID_HANDLE_VALUE != NULL the analyzer guesses that there
- * is a initialized HANDLE that is not freed properly.
- * Disable this return to stop confusing the analyzer. */
- #ifndef __clang_analyzer__
- if (!pFileSearch || (pFileSearch == INVALID_HANDLE_VALUE))
- return FALSE;
- #endif
- free(pFileSearch->lpPath);
- free(pFileSearch->lpPattern);
- if (pFileSearch->pDir)
- closedir(pFileSearch->pDir);
- free(pFileSearch);
- return TRUE;
- }
- BOOL CreateDirectoryA(LPCSTR lpPathName, LPSECURITY_ATTRIBUTES lpSecurityAttributes)
- {
- if (!mkdir(lpPathName, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)) {
- SetLastError(STATUS_SUCCESS);
- UnixChangeFileMode(lpPathName, 0xFFF);
- return TRUE;
- }
- SetLastError(map_posix_err(errno));
- return FALSE;
- }
- BOOL CreateDirectoryW(LPCWSTR lpPathName, LPSECURITY_ATTRIBUTES lpSecurityAttributes)
- {
- char* utfPathName = NULL;
- BOOL ret;
- if (ConvertFromUnicode(CP_UTF8, 0, lpPathName, -1, &utfPathName, 0, NULL, NULL) <= 0)
- {
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- return FALSE;
- }
- ret = CreateDirectoryA(utfPathName, lpSecurityAttributes);
- free(utfPathName);
- return ret;
- }
- BOOL RemoveDirectoryA(LPCSTR lpPathName)
- {
- int ret = rmdir(lpPathName);
- if (ret != 0)
- SetLastError(map_posix_err(errno));
- else
- SetLastError(STATUS_SUCCESS);
- return ret == 0;
- }
- BOOL RemoveDirectoryW(LPCWSTR lpPathName)
- {
- char* utfPathName = NULL;
- BOOL ret;
- if (ConvertFromUnicode(CP_UTF8, 0, lpPathName, -1, &utfPathName, 0, NULL, NULL) <= 0)
- {
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- return FALSE;
- }
- ret = RemoveDirectoryA(utfPathName);
- free(utfPathName);
- return ret;
- }
- BOOL MoveFileExA(LPCSTR lpExistingFileName, LPCSTR lpNewFileName, DWORD dwFlags)
- {
- struct stat st;
- int ret;
- ret = stat(lpNewFileName, &st);
- if ((dwFlags & MOVEFILE_REPLACE_EXISTING) == 0)
- {
- if (ret == 0)
- {
- SetLastError(ERROR_ALREADY_EXISTS);
- return FALSE;
- }
- }
- else
- {
- if (ret == 0 && (st.st_mode & S_IWUSR) == 0)
- {
- SetLastError(ERROR_ACCESS_DENIED);
- return FALSE;
- }
- }
- ret = rename(lpExistingFileName, lpNewFileName);
- UnixChangeFileMode(lpNewFileName, 0xFFF);
- if (ret != 0)
- SetLastError(map_posix_err(errno));
- return ret == 0;
- }
- BOOL MoveFileExW(LPCWSTR lpExistingFileName, LPCWSTR lpNewFileName, DWORD dwFlags)
- {
- LPSTR lpCExistingFileName;
- LPSTR lpCNewFileName;
- BOOL ret;
- if (ConvertFromUnicode(CP_UTF8, 0, lpExistingFileName, -1, &lpCExistingFileName, 0, NULL,
- NULL) <= 0)
- {
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- return FALSE;
- }
- if (ConvertFromUnicode(CP_UTF8, 0, lpNewFileName, -1, &lpCNewFileName, 0, NULL, NULL) <= 0)
- {
- free(lpCExistingFileName);
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- return FALSE;
- }
- ret = MoveFileExA(lpCExistingFileName, lpCNewFileName, dwFlags);
- free(lpCNewFileName);
- free(lpCExistingFileName);
- return ret;
- }
- BOOL MoveFileA(LPCSTR lpExistingFileName, LPCSTR lpNewFileName)
- {
- return MoveFileExA(lpExistingFileName, lpNewFileName, 0);
- }
- BOOL MoveFileW(LPCWSTR lpExistingFileName, LPCWSTR lpNewFileName)
- {
- return MoveFileExW(lpExistingFileName, lpNewFileName, 0);
- }
- BOOL CopyFileA(LPCSTR lpExistingFileName, LPCSTR lpNewFileName,BOOL bFailIfExists)
- {
- char buffer[1024];
- int len, n;
- int fd_to_read, fd_to_write;
- int exist = 0;
- if (access(lpNewFileName, F_OK) == 0)
- exist = 1;
- if (!!exist && bFailIfExists) {
- SetLastError(ERROR_ALREADY_EXISTS);
- return FALSE;
- }
- fd_to_read = open(lpExistingFileName, O_RDONLY);
- if(fd_to_read == -1) {
- WLog_WARN(TAG, "open the source file %s failed: %s", lpExistingFileName, strerror(errno));
- SetLastError(ERROR_FILE_NOT_FOUND);
- return FALSE;
- }
- fd_to_write = open(lpNewFileName, O_RDWR|O_CREAT, S_IWUSR|S_IRUSR|S_IXUSR);
- if(fd_to_write == -1) {
- WLog_ERR(TAG, "open the dest file %s failed: %s", lpNewFileName, strerror(errno));
- SetLastError(ERROR_CREATE_FAILED);
- close(fd_to_read);
- return FALSE;
- }
- if (exist) {
- ftruncate(fd_to_write, 0);
- lseek(fd_to_write, 0, SEEK_SET);
- }
- while((len = read(fd_to_read, buffer, 1024))) {
- n = write(fd_to_write, buffer, len);
- if(n != len) {
- SetLastError(ERROR_PARTIAL_COPY);
- WLog_ERR(TAG, "cp stream from src file %s to file %s failed: %s", lpExistingFileName, lpNewFileName, strerror(errno));
- close(fd_to_read);
- close(fd_to_write);
- return FALSE;
- }
- }
- close(fd_to_read);
- close(fd_to_write);
- UnixChangeFileMode(lpNewFileName, 0xFFF);
- #ifdef _DEBUG
- struct stat statsrc;
- if (stat(lpExistingFileName, &statsrc) == 0) {
- WLog_DBG(TAG, "src file %s size: %d", lpExistingFileName, statsrc.st_size);
- }
- struct stat statdst;
- if (stat(lpNewFileName, &statdst) == 0) {
- WLog_DBG(TAG, "dst file %s size: %d", lpNewFileName, statsrc.st_size);
- }
- #endif // _DEBUG
- return TRUE;
- }
- BOOL CopyFileW(LPCWSTR lpExistingFileName, LPCWSTR lpNewFileName, BOOL bFailIfExists)
- {
- LPSTR lpCExistingFileName;
- LPSTR lpCNewFileName;
- BOOL ret;
- if (ConvertFromUnicode(CP_UTF8, 0, lpExistingFileName, -1, &lpCExistingFileName, 0, NULL,
- NULL) <= 0)
- {
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- return FALSE;
- }
- if (ConvertFromUnicode(CP_UTF8, 0, lpNewFileName, -1, &lpCNewFileName, 0, NULL, NULL) <= 0)
- {
- free(lpCExistingFileName);
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- return FALSE;
- }
- ret = CopyFileA(lpCExistingFileName, lpCNewFileName, bFailIfExists);
- free(lpCNewFileName);
- free(lpCExistingFileName);
- return ret;
- }
- //BOOL SystemTimeToFileTime(CONST SYSTEMTIME *lpSystemTime, LPFILETIME lpFileTime)
- //{
- // SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- // return FALSE;
- //}
- #if 0
- BOOL FileTimeToLocalFileTime(CONST FILETIME *lpFileTime, LPFILETIME lpLocalFileTime)
- {
- LARGE_INTEGER local, utc;
- LONG bias;
- TIME_ZONE_INFORMATION tz;
- DWORD dwRes;
- utc.u.LowPart = lpFileTime->dwLowDateTime;
- utc.u.HighPart = lpFileTime->dwHighDateTime;
- {
- dwRes = GetTimeZoneInformation(&tz);
- if(dwRes != 0) {
- bias = tz.Bias;
- /* 1 ... TIME_ZONE_ID_STANDARD
- * 2 ... TIME_ZONE_ID_DAYLIGHT
- */
- bias += dwRes == 1 ? tz.StandardBias : tz.DaylightBias;
- bias *= SECSPERMIN;
- }
- local.QuadPart = utc.QuadPart - bias * (LONGLONG)TICKSPERSEC;
- }
- lpLocalFileTime->dwLowDateTime = local.u.LowPart;
- lpLocalFileTime->dwHighDateTime = local.u.HighPart;
- return TRUE;
- }
- #else
- //BOOL FileTimeToLocalFileTime(CONST FILETIME *lpFileTime, LPFILETIME lpLocalFileTime)
- //{
- // LARGE_INTEGER local, utc;
- // LONG bias;
- // TIME_ZONE_INFORMATION tz;
- // DWORD dwRes;
- //
- // utc.u.LowPart = lpFileTime->dwLowDateTime;
- // utc.u.HighPart = lpFileTime->dwHighDateTime;
- //
- // {
- // dwRes = GetTimeZoneInformation(&tz);
- // if(dwRes != 0) {
- // bias = tz.Bias;
- // /* 1 ... TIME_ZONE_ID_STANDARD
- // * 2 ... TIME_ZONE_ID_DAYLIGHT
- // */
- // bias += dwRes == 2 ? tz.DaylightBias : tz.StandardBias;
- // bias *= SECSPERMIN;
- // } else {
- // WLog_DBG(TAG, "GetTimeZoneInformation return zero !");
- // bias = tz.Bias;
- // bias += tz.StandardBias;
- // bias *= SECSPERMIN;
- // }
- //
- // local.QuadPart = utc.QuadPart - bias * (LONGLONG)TICKSPERSEC;
- // }
- //
- // lpLocalFileTime->dwLowDateTime = local.u.LowPart;
- // lpLocalFileTime->dwHighDateTime = local.u.HighPart;
- //
- // return TRUE;
- //}
- #endif
- BOOL LocalFileTimeToFileTime(CONST FILETIME *lpLocalFileTime, LPFILETIME lpFileTime)
- {
- WLog_ERR(TAG, "TODO: %s not implemented!", __FUNCTION__);
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
- }
- //BOOL FileTimeToSystemTime(CONST FILETIME *lpFileTime, LPSYSTEMTIME lpSystemTime)
- //{
- // SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- // return FALSE;
- //}
- LONG CompareFileTime(CONST FILETIME *lpFileTime1, CONST FILETIME *lpFileTime2)
- {
- WLog_ERR(TAG, "TODO: %s not implemented!", __FUNCTION__);
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
- }
- BOOL FileTimeToDosDateTime(CONST FILETIME *lpFileTime, LPWORD lpFatDate, LPWORD lpFatTime)
- {
- WLog_ERR(TAG, "TODO: %s not implemented!", __FUNCTION__);
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- *lpFatDate = 0;
- *lpFatTime = 0;
- return FALSE;
- }
- BOOL DosDateTimeToFileTime(WORD wFatDate, WORD wFatTime, LPFILETIME lpFileTime)
- {
- WLog_ERR(TAG, "TODO: %s not implemented!", __FUNCTION__);
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
- }
- #endif
- /* Extended API */
- int UnixChangeFileMode(const char* filename, int flags)
- {
- #ifndef _WIN32
- mode_t fl = 0;
- int res = 0;
- mode_t fm = umask(0);
- fl |= (flags & 0x4000) ? S_ISUID : 0;
- fl |= (flags & 0x2000) ? S_ISGID : 0;
- fl |= (flags & 0x1000) ? S_ISVTX : 0;
- fl |= (flags & 0x0400) ? S_IRUSR : 0;
- fl |= (flags & 0x0200) ? S_IWUSR : 0;
- fl |= (flags & 0x0100) ? S_IXUSR : 0;
- fl |= (flags & 0x0040) ? S_IRGRP : 0;
- fl |= (flags & 0x0020) ? S_IWGRP : 0;
- fl |= (flags & 0x0010) ? S_IXGRP : 0;
- fl |= (flags & 0x0004) ? S_IROTH : 0;
- fl |= (flags & 0x0002) ? S_IWOTH : 0;
- fl |= (flags & 0x0001) ? S_IXOTH : 0;
- res = chmod(filename, fl);
- umask(fm);
- return res;
- #else
- int rc;
- WCHAR* wfl = NULL;
- int fl = 0;
- if (ConvertToUnicode(CP_UTF8, 0, filename, -1, &wfl, 0) <= 0)
- return -1;
- /* Check for unsupported flags. */
- if (flags & ~(_S_IREAD | _S_IWRITE))
- WLog_WARN(TAG, "Unsupported file mode %d for _wchmod", flags);
- rc = _wchmod(wfl, flags);
- free(wfl);
- return rc;
- #endif
- }
|