| 1 | /* $Id: os2fake-win.c,v 1.1 2001-03-14 20:14:35 bird Exp $ | 
|---|
| 2 | * | 
|---|
| 3 | * OS/2 Fake library for Win32. | 
|---|
| 4 | * | 
|---|
| 5 | * Copyright (c) 2001 knut st. osmundsen (knut.stange.osmundsen@mynd.no) | 
|---|
| 6 | * | 
|---|
| 7 | * Project Odin Software License can be found in LICENSE.TXT | 
|---|
| 8 | * | 
|---|
| 9 | */ | 
|---|
| 10 |  | 
|---|
| 11 |  | 
|---|
| 12 | /******************************************************************************* | 
|---|
| 13 | *   Defined Constants And Macros                                               * | 
|---|
| 14 | *******************************************************************************/ | 
|---|
| 15 | #define VALIDPTR(pv) (((PVOID)pv) >= (PVOID)0x10000 && ((PVOID)pv) <= (PVOID)0xc0000000) | 
|---|
| 16 |  | 
|---|
| 17 |  | 
|---|
| 18 |  | 
|---|
| 19 | /******************************************************************************* | 
|---|
| 20 | *   Header Files                                                               * | 
|---|
| 21 | *******************************************************************************/ | 
|---|
| 22 | #include <windows.h> | 
|---|
| 23 | #include <string.h> | 
|---|
| 24 | #include <stdio.h> | 
|---|
| 25 |  | 
|---|
| 26 | #include "os2fake.h" | 
|---|
| 27 |  | 
|---|
| 28 |  | 
|---|
| 29 | /******************************************************************************* | 
|---|
| 30 | *   Internal Functions                                                         * | 
|---|
| 31 | *******************************************************************************/ | 
|---|
| 32 | static ULONG ConvertAttributes(DWORD dwFileAttributes); | 
|---|
| 33 | static ULONG ConvertFileTime(PFILETIME pFileTime); | 
|---|
| 34 |  | 
|---|
| 35 | /** | 
|---|
| 36 | * Converts Win32 file attribute to OS/2 file attributes. | 
|---|
| 37 | * @returns OS/2 fileattributes. | 
|---|
| 38 | * @param   dwFileAttributes    Win32 fileattributes. | 
|---|
| 39 | */ | 
|---|
| 40 | ULONG ConvertAttributes(DWORD dwFileAttributes) | 
|---|
| 41 | { | 
|---|
| 42 | static struct _ConvAttr | 
|---|
| 43 | { | 
|---|
| 44 | ULONG   ulWin; | 
|---|
| 45 | ULONG   ulOs2; | 
|---|
| 46 | }       aConvAttr[] = | 
|---|
| 47 | { | 
|---|
| 48 | {FILE_ATTRIBUTE_READONLY,   FILE_READONLY}, | 
|---|
| 49 | {FILE_ATTRIBUTE_HIDDEN,     FILE_HIDDEN}, | 
|---|
| 50 | {FILE_ATTRIBUTE_SYSTEM,     FILE_SYSTEM}, | 
|---|
| 51 | {FILE_ATTRIBUTE_DIRECTORY,  FILE_DIRECTORY}, | 
|---|
| 52 | {FILE_ATTRIBUTE_ARCHIVE,    FILE_ARCHIVED} | 
|---|
| 53 | }; | 
|---|
| 54 | ULONG   ulOS2Attr = 0; | 
|---|
| 55 | int     i; | 
|---|
| 56 |  | 
|---|
| 57 | for (i = 0; i < sizeof(aConvAttr) / sizeof(aConvAttr[0]); i++) | 
|---|
| 58 | if (dwFileAttributes & aConvAttr[i].ulWin) | 
|---|
| 59 | ulOS2Attr |= aConvAttr[i].ulOs2; | 
|---|
| 60 |  | 
|---|
| 61 | return ulOS2Attr; | 
|---|
| 62 | } | 
|---|
| 63 |  | 
|---|
| 64 |  | 
|---|
| 65 | /** | 
|---|
| 66 | * Converts Win32 filetime to OS/2 filetime. | 
|---|
| 67 | * @returns OS/2 filetime. | 
|---|
| 68 | * @param   pFileTime   Pointer to Win32 filetime. | 
|---|
| 69 | */ | 
|---|
| 70 | ULONG ConvertFileTime(PFILETIME pFileTime) | 
|---|
| 71 | { | 
|---|
| 72 | ULONG       ulOS2FileTime; | 
|---|
| 73 | SYSTEMTIME  SystemTime; | 
|---|
| 74 |  | 
|---|
| 75 | if (   FileTimeToSystemTime(pFileTime, &SystemTime) | 
|---|
| 76 | && SystemTime.wYear >= 1980 && SystemTime.wYear < (1980 + 0x7F)) | 
|---|
| 77 | { | 
|---|
| 78 | ulOS2FileTime =    SystemTime.wDay | 
|---|
| 79 | | (SystemTime.wMonth << 5) | 
|---|
| 80 | | (((SystemTime.wYear - 1980) & 0x7F) << (5+4)) | 
|---|
| 81 | | ((SystemTime.wSecond / 2) << (16)) | 
|---|
| 82 | | (SystemTime.wMinute << (16+5)) | 
|---|
| 83 | | (SystemTime.wHour << (16+5+6)); | 
|---|
| 84 | } | 
|---|
| 85 | else | 
|---|
| 86 | ulOS2FileTime = 0; | 
|---|
| 87 |  | 
|---|
| 88 | return ulOS2FileTime; | 
|---|
| 89 | } | 
|---|
| 90 |  | 
|---|
| 91 |  | 
|---|
| 92 |  | 
|---|
| 93 | APIRET OS2ENTRY         DosQueryPathInfo( | 
|---|
| 94 | PCSZ        pszPathName, | 
|---|
| 95 | ULONG       ulInfoLevel, | 
|---|
| 96 | PVOID       pInfoBuf, | 
|---|
| 97 | ULONG       cbInfoBuf) | 
|---|
| 98 | { | 
|---|
| 99 | APIRET  rc;                         /* Return code. */ | 
|---|
| 100 |  | 
|---|
| 101 | if (!VALIDPTR(pszPathName)) | 
|---|
| 102 | { | 
|---|
| 103 | fprintf(stderr, "DosQueryPathInfo: pszPathName is an invalid pointer - %p\n", pszPathName); | 
|---|
| 104 | return ERROR_INVALID_PARAMETER; | 
|---|
| 105 | } | 
|---|
| 106 |  | 
|---|
| 107 | if (!VALIDPTR(pInfoBuf)) | 
|---|
| 108 | { | 
|---|
| 109 | fprintf(stderr, "DosQueryPathInfo: pInfoBuf is an invalid pointer - %p\n", pInfoBuf); | 
|---|
| 110 | return ERROR_INVALID_PARAMETER; | 
|---|
| 111 | } | 
|---|
| 112 |  | 
|---|
| 113 |  | 
|---|
| 114 | rc = ERROR_INVALID_PARAMETER; | 
|---|
| 115 | switch (ulInfoLevel) | 
|---|
| 116 | { | 
|---|
| 117 | case FIL_QUERYFULLNAME: | 
|---|
| 118 | { | 
|---|
| 119 | LPTSTR   lpDummy; | 
|---|
| 120 | if (GetFullPathName(pszPathName, cbInfoBuf, pInfoBuf, &lpDummy) > 0) | 
|---|
| 121 | rc = NO_ERROR; | 
|---|
| 122 | else | 
|---|
| 123 | rc = GetLastError(); | 
|---|
| 124 | break; | 
|---|
| 125 | } | 
|---|
| 126 |  | 
|---|
| 127 | case FIL_STANDARD: | 
|---|
| 128 | if (cbInfoBuf == sizeof(FILESTATUS3)) | 
|---|
| 129 | { | 
|---|
| 130 | WIN32_FILE_ATTRIBUTE_DATA   fad; | 
|---|
| 131 |  | 
|---|
| 132 | if (GetFileAttributesEx(pszPathName, GetFileExInfoStandard, &fad)) //W98, NT4 and above. | 
|---|
| 133 | { | 
|---|
| 134 | PFILESTATUS3    pfst3 = (PFILESTATUS3)(pInfoBuf); | 
|---|
| 135 |  | 
|---|
| 136 | if (fad.nFileSizeHigh > 0) | 
|---|
| 137 | rc = ERROR_BAD_LENGTH; | 
|---|
| 138 | pfst3->cbFile = pfst3->cbFileAlloc = fad.nFileSizeLow; | 
|---|
| 139 | pfst3->attrFile = ConvertAttributes(fad.dwFileAttributes); | 
|---|
| 140 | *(PULONG)(&pfst3->fdateCreation) = ConvertFileTime(&fad.ftCreationTime); | 
|---|
| 141 | *(PULONG)(&pfst3->fdateLastAccess) = ConvertFileTime(&fad.ftLastAccessTime); | 
|---|
| 142 | *(PULONG)(&pfst3->fdateLastWrite) = ConvertFileTime(&fad.ftLastWriteTime); | 
|---|
| 143 | rc = NO_ERROR; | 
|---|
| 144 | } | 
|---|
| 145 | else | 
|---|
| 146 | rc = GetLastError(); | 
|---|
| 147 | } | 
|---|
| 148 | else | 
|---|
| 149 | fprintf(stderr, "DosQueryPathInfo: FIL_STANDARD - invalid structure size (cbInfoBuf=%d)\n", cbInfoBuf); | 
|---|
| 150 | break; | 
|---|
| 151 |  | 
|---|
| 152 | default: | 
|---|
| 153 | fprintf(stderr, "DosQueryPathInfo: ulInfoLevel=%d not supported\n", ulInfoLevel); | 
|---|
| 154 | } | 
|---|
| 155 |  | 
|---|
| 156 | return rc; | 
|---|
| 157 | } | 
|---|
| 158 |  | 
|---|
| 159 |  | 
|---|
| 160 | APIRET OS2ENTRY         DosFindFirst( | 
|---|
| 161 | PCSZ        pszFileSpec, | 
|---|
| 162 | PHDIR       phdir, | 
|---|
| 163 | ULONG       flAttribute, | 
|---|
| 164 | PVOID       pFindBuf, | 
|---|
| 165 | ULONG       cbFindBuf, | 
|---|
| 166 | PULONG      pcFileNames, | 
|---|
| 167 | ULONG       ulInfoLevel) | 
|---|
| 168 | { | 
|---|
| 169 | WIN32_FIND_DATA FindData;           /* Win32 Find data (returned by FindFirstFile) */ | 
|---|
| 170 | APIRET          rc; | 
|---|
| 171 |  | 
|---|
| 172 | if (!VALIDPTR(pszFileSpec)) | 
|---|
| 173 | { | 
|---|
| 174 | fprintf(stderr, "DosFindFirst: pszFileSpec - %p\n", pszFileSpec); | 
|---|
| 175 | return ERROR_INVALID_PARAMETER; | 
|---|
| 176 | } | 
|---|
| 177 |  | 
|---|
| 178 | if (!VALIDPTR(phdir)) | 
|---|
| 179 | { | 
|---|
| 180 | fprintf(stderr, "DosFindFirst: phdir - %p\n", phdir); | 
|---|
| 181 | return ERROR_INVALID_PARAMETER; | 
|---|
| 182 | } | 
|---|
| 183 |  | 
|---|
| 184 | if (!VALIDPTR(pFindBuf)) | 
|---|
| 185 | { | 
|---|
| 186 | fprintf(stderr, "DosFindFirst: pfindbuf - %p\n", pFindBuf); | 
|---|
| 187 | return ERROR_INVALID_PARAMETER; | 
|---|
| 188 | } | 
|---|
| 189 |  | 
|---|
| 190 | if (!VALIDPTR(pcFileNames)) | 
|---|
| 191 | { | 
|---|
| 192 | fprintf(stderr, "DosFindFirst: pcFileNames - %p\n", pcFileNames); | 
|---|
| 193 | return ERROR_INVALID_PARAMETER; | 
|---|
| 194 | } | 
|---|
| 195 |  | 
|---|
| 196 | if (*phdir != HDIR_CREATE) | 
|---|
| 197 | { | 
|---|
| 198 | fprintf(stderr, "DosFindFirst: *phdir != HDIR_CREATE - 0x%08x\n", *phdir); | 
|---|
| 199 | return ERROR_INVALID_PARAMETER; | 
|---|
| 200 | } | 
|---|
| 201 |  | 
|---|
| 202 | switch (ulInfoLevel) | 
|---|
| 203 | { | 
|---|
| 204 | case FIL_STANDARD: | 
|---|
| 205 | if (cbFindBuf < sizeof(FILEFINDBUF3)) | 
|---|
| 206 | { | 
|---|
| 207 | fprintf(stderr, "DosFindFirst: unsupported buffer size - %d\n", cbFindBuf); | 
|---|
| 208 | return ERROR_INVALID_PARAMETER; | 
|---|
| 209 | } | 
|---|
| 210 | break; | 
|---|
| 211 |  | 
|---|
| 212 | default: | 
|---|
| 213 | fprintf(stderr, "DosFindFirst: invalid infolevel %d\n", ulInfoLevel); | 
|---|
| 214 | return ERROR_INVALID_PARAMETER; | 
|---|
| 215 | } | 
|---|
| 216 |  | 
|---|
| 217 | *phdir = (HDIR)FindFirstFile(pszFileSpec, &FindData); | 
|---|
| 218 | if (*phdir != (HDIR)INVALID_HANDLE_VALUE) | 
|---|
| 219 | { | 
|---|
| 220 | PFILEFINDBUF3   pfindbuf = (PFILEFINDBUF3)pFindBuf; | 
|---|
| 221 |  | 
|---|
| 222 | memcpy(pfindbuf->achName, FindData.cFileName, pfindbuf->cchName = strlen(FindData.cFileName) + 1); | 
|---|
| 223 | pfindbuf->cbFile = pfindbuf->cbFileAlloc = FindData.nFileSizeHigh > 0 ? 0xffffffff : FindData.nFileSizeLow; | 
|---|
| 224 | pfindbuf->attrFile = ConvertAttributes(FindData.dwFileAttributes); | 
|---|
| 225 | *(PULONG)(&pfindbuf->fdateCreation) = ConvertFileTime(&FindData.ftCreationTime); | 
|---|
| 226 | *(PULONG)(&pfindbuf->fdateLastAccess) = ConvertFileTime(&FindData.ftLastAccessTime); | 
|---|
| 227 | *(PULONG)(&pfindbuf->fdateLastWrite) = ConvertFileTime(&FindData.ftLastWriteTime); | 
|---|
| 228 | pfindbuf->oNextEntryOffset = 0; | 
|---|
| 229 | *pcFileNames = 1; | 
|---|
| 230 | rc = NO_ERROR; | 
|---|
| 231 | } | 
|---|
| 232 | else | 
|---|
| 233 | rc = GetLastError(); | 
|---|
| 234 |  | 
|---|
| 235 | return rc; | 
|---|
| 236 | } | 
|---|
| 237 |  | 
|---|
| 238 |  | 
|---|
| 239 | APIRET OS2ENTRY         DosFindNext( | 
|---|
| 240 | HDIR        hDir, | 
|---|
| 241 | PVOID       pFindBuf, | 
|---|
| 242 | ULONG       cbFindBuf, | 
|---|
| 243 | PULONG      pcFileNames) | 
|---|
| 244 | { | 
|---|
| 245 | WIN32_FIND_DATA FindData;           /* Win32 Find data (returned by FindFirstFile) */ | 
|---|
| 246 | APIRET          rc; | 
|---|
| 247 |  | 
|---|
| 248 | if (!VALIDPTR(pFindBuf)) | 
|---|
| 249 | { | 
|---|
| 250 | fprintf(stderr, "DosFindNext: pfindbuf - %p\n", pFindBuf); | 
|---|
| 251 | return ERROR_INVALID_PARAMETER; | 
|---|
| 252 | } | 
|---|
| 253 |  | 
|---|
| 254 | if (cbFindBuf < sizeof(FILEFINDBUF3)) | 
|---|
| 255 | { | 
|---|
| 256 | fprintf(stderr, "DosFindNext: unsupported buffer size - %d\n", cbFindBuf); | 
|---|
| 257 | return ERROR_INVALID_PARAMETER; | 
|---|
| 258 | } | 
|---|
| 259 |  | 
|---|
| 260 | if (!VALIDPTR(pcFileNames)) | 
|---|
| 261 | { | 
|---|
| 262 | fprintf(stderr, "DosFindNext: pcFileNames - %p\n", pcFileNames); | 
|---|
| 263 | return ERROR_INVALID_PARAMETER; | 
|---|
| 264 | } | 
|---|
| 265 |  | 
|---|
| 266 | if (FindNextFile((HANDLE)hDir, &FindData)) | 
|---|
| 267 | { | 
|---|
| 268 | PFILEFINDBUF3   pfindbuf = (PFILEFINDBUF3)pFindBuf; | 
|---|
| 269 |  | 
|---|
| 270 | memcpy(pfindbuf->achName, FindData.cFileName, pfindbuf->cchName = strlen(FindData.cFileName) + 1); | 
|---|
| 271 | pfindbuf->cbFile = pfindbuf->cbFileAlloc = FindData.nFileSizeHigh > 0 ? 0xffffffff : FindData.nFileSizeLow; | 
|---|
| 272 | pfindbuf->attrFile = ConvertAttributes(FindData.dwFileAttributes); | 
|---|
| 273 | *(PULONG)(&pfindbuf->fdateCreation) = ConvertFileTime(&FindData.ftCreationTime); | 
|---|
| 274 | *(PULONG)(&pfindbuf->fdateLastAccess) = ConvertFileTime(&FindData.ftLastAccessTime); | 
|---|
| 275 | *(PULONG)(&pfindbuf->fdateLastWrite) = ConvertFileTime(&FindData.ftLastWriteTime); | 
|---|
| 276 | pfindbuf->oNextEntryOffset = 0; | 
|---|
| 277 | *pcFileNames = 1; | 
|---|
| 278 | rc = NO_ERROR; | 
|---|
| 279 | } | 
|---|
| 280 | else | 
|---|
| 281 | rc = GetLastError(); | 
|---|
| 282 |  | 
|---|
| 283 | return rc; | 
|---|
| 284 |  | 
|---|
| 285 | } | 
|---|
| 286 |  | 
|---|
| 287 |  | 
|---|
| 288 | APIRET OS2ENTRY         DosFindClose( | 
|---|
| 289 | HDIR        hDir) | 
|---|
| 290 | { | 
|---|
| 291 | if (FindClose((HANDLE)hDir)) | 
|---|
| 292 | return NO_ERROR; | 
|---|
| 293 | return ERROR_INVALID_HANDLE; | 
|---|
| 294 | } | 
|---|
| 295 |  | 
|---|
| 296 |  | 
|---|
| 297 |  | 
|---|