Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Rework the win32 OS driver to use malloc()/free() directly rather than going through the SQLite memory allocation layer. With this change, the complete quick.test script now runs on windows. There are a few errors, but no segfaults. Progress. (CVS 4289) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
75aad316981690d7a93ea6ac1c187f7d |
User & Date: | drh 2007-08-24 17:52:22.000 |
Context
2007-08-24
| ||
18:32 | fix cleanup by removing sqlite3.pc (generated by 'configure') on 'make distclean', too (CVS 4290) (check-in: 3c90864835 user: rse tags: trunk) | |
17:52 | Rework the win32 OS driver to use malloc()/free() directly rather than going through the SQLite memory allocation layer. With this change, the complete quick.test script now runs on windows. There are a few errors, but no segfaults. Progress. (CVS 4289) (check-in: 75aad31698 user: drh tags: trunk) | |
16:29 | Fix bugs in temp database handling introduced by the prevous check-in. (CVS 4288) (check-in: 300038be93 user: drh tags: trunk) | |
Changes
Changes to src/os_win.c.
︙ | ︙ | |||
11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ****************************************************************************** ** ** This file contains code that is specific to windows. */ #include "sqliteInt.h" #if OS_WIN /* This file is used for windows only */ #include <winbase.h> #ifdef __CYGWIN__ # include <sys/cygwin.h> #endif /* | > > > > > > > > > > > > > > > > > > > > > > > > > > > | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | ****************************************************************************** ** ** This file contains code that is specific to windows. */ #include "sqliteInt.h" #if OS_WIN /* This file is used for windows only */ /* ** A Note About Memory Allocation: ** ** This driver uses malloc()/free() directly rather than going through ** the SQLite-wrappers sqlite3_malloc()/sqlite3_free(). Those wrappers ** are designed for use on embedded systems where memory is scarce and ** malloc failures happen frequently. Win32 does not typically run on ** embedded systems, and when it does the developers normally have bigger ** problems to worry about than running out of memory. So there is not ** a compelling need to use the wrappers. ** ** But there is a good reason to not use the wrappers. If we use the ** wrappers then we will get simulated malloc() failures within this ** driver. And that causes all kinds of problems for our tests. We ** could enhance SQLite to deal with simulated malloc failures within ** the OS driver, but the code to deal with those failure would not ** be exercised on Linux (which does not need to malloc() in the driver) ** and so we would have difficulty writing coverage tests for that ** code. Better to leave the code out, we think. ** ** The point of this discussion is as follows: When creating a new ** OS layer for an embedded system, if you use this file as an example, ** avoid the use of malloc()/free(). Those routines work ok on windows ** desktops but not so well in embedded systems. */ #include <winbase.h> #ifdef __CYGWIN__ # include <sys/cygwin.h> #endif /* |
︙ | ︙ | |||
119 120 121 122 123 124 125 | return sqlite3_os_type==2; } #endif /* OS_WINCE */ /* ** Convert a UTF-8 string to microsoft unicode (UTF-16?). ** | | | | | | | | | | | | | | | | | | 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 | return sqlite3_os_type==2; } #endif /* OS_WINCE */ /* ** Convert a UTF-8 string to microsoft unicode (UTF-16?). ** ** Space to hold the returned string is obtained from malloc. */ static WCHAR *utf8ToUnicode(const char *zFilename){ int nChar; WCHAR *zWideFilename; nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0); zWideFilename = malloc( nChar*sizeof(zWideFilename[0]) ); if( zWideFilename==0 ){ return 0; } nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename, nChar); if( nChar==0 ){ free(zWideFilename); zWideFilename = 0; } return zWideFilename; } /* ** Convert microsoft unicode to UTF-8. Space to hold the returned string is ** obtained from malloc(). */ static char *unicodeToUtf8(const WCHAR *zWideFilename){ int nByte; char *zFilename; nByte = WideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, 0, 0, 0, 0); zFilename = malloc( nByte ); if( zFilename==0 ){ return 0; } nByte = WideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, zFilename, nByte, 0, 0); if( nByte == 0 ){ free(zFilename); zFilename = 0; } return zFilename; } /* ** Convert an ansi string to microsoft unicode, based on the ** current codepage settings for file apis. ** ** Space to hold the returned string is obtained ** from malloc. */ static WCHAR *mbcsToUnicode(const char *zFilename){ int nByte; WCHAR *zMbcsFilename; int codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP; nByte = MultiByteToWideChar(codepage, 0, zFilename, -1, NULL,0)*sizeof(WCHAR); zMbcsFilename = malloc( nByte*sizeof(zMbcsFilename[0]) ); if( zMbcsFilename==0 ){ return 0; } nByte = MultiByteToWideChar(codepage, 0, zFilename, -1, zMbcsFilename, nByte); if( nByte==0 ){ free(zMbcsFilename); zMbcsFilename = 0; } return zMbcsFilename; } /* ** Convert microsoft unicode to multibyte character string, based on the ** user's Ansi codepage. ** ** Space to hold the returned string is obtained from ** malloc(). */ static char *unicodeToMbcs(const WCHAR *zWideFilename){ int nByte; char *zFilename; int codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP; nByte = WideCharToMultiByte(codepage, 0, zWideFilename, -1, 0, 0, 0, 0); zFilename = malloc( nByte ); if( zFilename==0 ){ return 0; } nByte = WideCharToMultiByte(codepage, 0, zWideFilename, -1, zFilename, nByte, 0, 0); if( nByte == 0 ){ free(zFilename); zFilename = 0; } return zFilename; } /* ** Convert multibyte character string to UTF-8. Space to hold the ** returned string is obtained from malloc(). */ static char *mbcsToUtf8(const char *zFilename){ char *zFilenameUtf8; WCHAR *zTmpWide; zTmpWide = mbcsToUnicode(zFilename); if( zTmpWide==0 ){ return 0; } zFilenameUtf8 = unicodeToUtf8(zTmpWide); free(zTmpWide); return zFilenameUtf8; } /* ** Convert UTF-8 to multibyte character string. Space to hold the ** returned string is obtained from malloc(). */ static char *utf8ToMbcs(const char *zFilename){ char *zFilenameMbcs; WCHAR *zTmpWide; zTmpWide = utf8ToUnicode(zFilename); if( zTmpWide==0 ){ return 0; } zFilenameMbcs = unicodeToMbcs(zTmpWide); free(zTmpWide); return zFilenameMbcs; } #if OS_WINCE /************************************************************************* ** This section contains code for WinCE only. */ |
︙ | ︙ | |||
321 322 323 324 325 326 327 | for (;*zTok;zTok++){ if (*zTok == '\\') *zTok = '_'; } /* Create/open the named mutex */ pFile->hMutex = CreateMutexW(NULL, FALSE, zName); if (!pFile->hMutex){ | | | 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 | for (;*zTok;zTok++){ if (*zTok == '\\') *zTok = '_'; } /* Create/open the named mutex */ pFile->hMutex = CreateMutexW(NULL, FALSE, zName); if (!pFile->hMutex){ free(zName); return FALSE; } /* Acquire the mutex before continuing */ winceMutexAcquire(pFile->hMutex); /* Since the names of named mutexes, semaphores, file mappings etc are |
︙ | ︙ | |||
343 344 345 346 347 348 349 | /* Set a flag that indicates we're the first to create the memory so it ** must be zero-initialized */ if (GetLastError() == ERROR_ALREADY_EXISTS){ bInit = FALSE; } | | | 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 | /* Set a flag that indicates we're the first to create the memory so it ** must be zero-initialized */ if (GetLastError() == ERROR_ALREADY_EXISTS){ bInit = FALSE; } free(zName); /* If we succeeded in making the shared memory handle, map it. */ if (pFile->hShared){ pFile->shared = (winceLock*)MapViewOfFile(pFile->hShared, FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, sizeof(winceLock)); /* If mapping failed, close the shared memory handle and erase it */ if (!pFile->shared){ |
︙ | ︙ | |||
402 403 404 405 406 407 408 | /* De-reference and close our copy of the shared memory handle */ UnmapViewOfFile(pFile->shared); CloseHandle(pFile->hShared); if( pFile->zDeleteOnClose ){ DeleteFileW(pFile->zDeleteOnClose); | | | 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 | /* De-reference and close our copy of the shared memory handle */ UnmapViewOfFile(pFile->shared); CloseHandle(pFile->hShared); if( pFile->zDeleteOnClose ){ DeleteFileW(pFile->zDeleteOnClose); free(pFile->zDeleteOnClose); pFile->zDeleteOnClose = 0; } /* Done with the mutex */ winceMutexRelease(pFile->hMutex); CloseHandle(pFile->hMutex); pFile->hMutex = NULL; |
︙ | ︙ | |||
1012 1013 1014 1015 1016 1017 1018 | ** ** The next block of code implements the VFS methods. ****************************************************************************/ /* ** Convert a UTF-8 filename into whatever form the underlying ** operating system wants filenames in. Space to hold the result | | | 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 | ** ** The next block of code implements the VFS methods. ****************************************************************************/ /* ** Convert a UTF-8 filename into whatever form the underlying ** operating system wants filenames in. Space to hold the result ** is obtained from malloc and must be freed by the calling ** function. */ static void *convertUtf8Filename(const char *zFilename){ void *zConverted = 0; if( isNT() ){ zConverted = utf8ToUnicode(zFilename); }else{ |
︙ | ︙ | |||
1100 1101 1102 1103 1104 1105 1106 | dwFlagsAndAttributes, NULL ); #endif } if( h==INVALID_HANDLE_VALUE ){ if( flags & SQLITE_OPEN_READWRITE ){ | | | 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 | dwFlagsAndAttributes, NULL ); #endif } if( h==INVALID_HANDLE_VALUE ){ if( flags & SQLITE_OPEN_READWRITE ){ free(zConverted); return winOpen(0, zName, id, ((flags|SQLITE_OPEN_READONLY)&~SQLITE_OPEN_READWRITE), pOutFlags); }else{ return SQLITE_CANTOPEN; } } if( pOutFlags ){ |
︙ | ︙ | |||
1123 1124 1125 1126 1127 1128 1129 | pFile->h = h; #if OS_WINCE if( (flags & (SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_DB)) == (SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_DB) && !winceCreateLock(zFilename, &f) ){ CloseHandle(h); | | | | 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 | pFile->h = h; #if OS_WINCE if( (flags & (SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_DB)) == (SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_DB) && !winceCreateLock(zFilename, &f) ){ CloseHandle(h); free(zConverted); return SQLITE_CANTOPEN; } if( dwFlagsAndAttributes & FILE_FLAG_DELETEONCLOSE ){ pFile->zDeleteOnClose = zConverted; }else #endif { free(zConverted); } return SQLITE_OK; } /* ** Delete the named file. ** |
︙ | ︙ | |||
1176 1177 1178 1179 1180 1181 1182 | #else do{ rc = DeleteFileA(zConverted); }while( rc==0 && GetFileAttributesA(zConverted)!=0xffffffff && cnt++ < MX_DELETION_ATTEMPTS && (Sleep(100), 1) ); #endif } | | | 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 | #else do{ rc = DeleteFileA(zConverted); }while( rc==0 && GetFileAttributesA(zConverted)!=0xffffffff && cnt++ < MX_DELETION_ATTEMPTS && (Sleep(100), 1) ); #endif } free(zConverted); OSTRACE2("DELETE \"%s\"\n", zFilename); return rc!=0 ? SQLITE_OK : SQLITE_IOERR; } /* ** Check the existance and status of a file. */ |
︙ | ︙ | |||
1204 1205 1206 1207 1208 1209 1210 | }else{ #if OS_WINCE return SQLITE_NOMEM; #else attr = GetFileAttributesA((char*)zConverted); #endif } | | | 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 | }else{ #if OS_WINCE return SQLITE_NOMEM; #else attr = GetFileAttributesA((char*)zConverted); #endif } free(zConverted); switch( flags ){ case SQLITE_ACCESS_EXISTS: rc = attr!=0xffffffff; break; case SQLITE_ACCESS_READWRITE: rc = (attr & FILE_ATTRIBUTE_READONLY)==0; break; |
︙ | ︙ | |||
1241 1242 1243 1244 1245 1246 1247 | sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", sqlite3_temp_directory); }else if( isNT() ){ char *zMulti; WCHAR zWidePath[MAX_PATH]; GetTempPathW(MAX_PATH-30, zWidePath); zMulti = unicodeToUtf8(zWidePath); if( zMulti ){ | | > | > | 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 | sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", sqlite3_temp_directory); }else if( isNT() ){ char *zMulti; WCHAR zWidePath[MAX_PATH]; GetTempPathW(MAX_PATH-30, zWidePath); zMulti = unicodeToUtf8(zWidePath); if( zMulti ){ sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zMulti); free(zMulti); }else{ return SQLITE_NOMEM; } }else{ char *zUtf8; char zMbcsPath[MAX_PATH]; GetTempPathA(MAX_PATH-30, zMbcsPath); zUtf8 = mbcsToUtf8(zMbcsPath); if( zUtf8 ){ sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zUtf8); free(zUtf8); }else{ return SQLITE_NOMEM; } } for(i=strlen(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){} zTempPath[i] = 0; for(;;){ |
︙ | ︙ | |||
1302 1303 1304 1305 1306 1307 1308 | int nByte; void *zConverted; char *zOut; zConverted = convertUtf8Filename(zRelative); if( isNT() ){ WCHAR *zTemp; nByte = GetFullPathNameW((WCHAR*)zConverted, 0, 0, 0) + 3; | | | | | | | | | | > | 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 | int nByte; void *zConverted; char *zOut; zConverted = convertUtf8Filename(zRelative); if( isNT() ){ WCHAR *zTemp; nByte = GetFullPathNameW((WCHAR*)zConverted, 0, 0, 0) + 3; zTemp = malloc( nByte*sizeof(zTemp[0]) ); if( zTemp==0 ){ free(zConverted); return SQLITE_NOMEM; } GetFullPathNameW((WCHAR*)zConverted, nByte, zTemp, 0); free(zConverted); zOut = unicodeToUtf8(zTemp); free(zTemp); }else{ char *zTemp; nByte = GetFullPathNameA((char*)zConverted, 0, 0, 0) + 3; zTemp = malloc( nByte*sizeof(zTemp[0]) ); if( zTemp==0 ){ free(zConverted); return SQLITE_NOMEM; } GetFullPathNameA((char*)zConverted, nByte, zTemp, 0); free(zConverted); zOut = mbcsToUtf8(zTemp); free(zTemp); } if( zOut ){ sqlite3_snprintf(pVfs->mxPathname, zFull, "%s", zOut); free(zOut); return SQLITE_OK; }else{ return SQLITE_NOMEM; } #endif } |
︙ | ︙ | |||
1357 1358 1359 1360 1361 1362 1363 | }else{ #if OS_WINCE return 0; #else h = LoadLibraryA((char*)zConverted); #endif } | | | 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 | }else{ #if OS_WINCE return 0; #else h = LoadLibraryA((char*)zConverted); #endif } free(zConverted); return (void*)h; } static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){ FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), |
︙ | ︙ |