FreeCalypso > hg > leo2moko-debug
comparison g23m/condat/com/src/driver/ffs_pc.c @ 0:509db1a7b7b8
initial import: leo2moko-r1
| author | Space Falcon <falcon@ivan.Harhan.ORG> |
|---|---|
| date | Mon, 01 Jun 2015 03:24:05 +0000 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:509db1a7b7b8 |
|---|---|
| 1 /********************************************************************************/ | |
| 2 /* */ | |
| 3 /* File Name: ffs_pc.c */ | |
| 4 /* */ | |
| 5 /* Purpose: This file contains the internal functions related to */ | |
| 6 /* the Flash File System. */ | |
| 7 /* */ | |
| 8 /* Note: None. */ | |
| 9 /* */ | |
| 10 /* Revision History: */ | |
| 11 /* 02/27/02 Pascal Pompei */ | |
| 12 /* - Create. */ | |
| 13 /* */ | |
| 14 /* (C) Copyright 2002 by Texas Instruments Incorporated, All Rights Reserved. */ | |
| 15 /* */ | |
| 16 /********************************************************************************/ | |
| 17 | |
| 18 #include "ffs_pc_api.h" | |
| 19 | |
| 20 /********************************* NAME LENGTHS *********************************/ | |
| 21 /* */ | |
| 22 /* Define the maximum lengths. */ | |
| 23 #define FFS_MAX_PATH_LENGTH (MAX_PATH) | |
| 24 #define FFS_MAX_OBJECT_LENGTH (20) | |
| 25 | |
| 26 | |
| 27 /*************************** INTERNAL FILE DESCRIPTOR ***************************/ | |
| 28 /* */ | |
| 29 /* Define the internal file descriptor. */ | |
| 30 /* */ | |
| 31 /* __ Open the file for appending. */ | |
| 32 /* | __ File handle (30 bits). */ | |
| 33 /* __|______________________________|_____________________________ */ | |
| 34 /* | ¦ ¦ | */ | |
| 35 /* |0¦ ¦ | */ | |
| 36 /* |_¦_¦_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._| */ | |
| 37 typedef union | |
| 38 { | |
| 39 INT32 fd; | |
| 40 struct | |
| 41 { | |
| 42 INT32 handle : 30; | |
| 43 INT32 append : 1; | |
| 44 } ifd; | |
| 45 } T_FFS_IFD; | |
| 46 | |
| 47 | |
| 48 /* Define the directory nesting depth. */ | |
| 49 #define FFS_DIR_NESTING_DEPTH (0x06) | |
| 50 | |
| 51 /* Define the directory dedicated to the Flash File System. */ | |
| 52 #define FFS_DIR ("C:\\FFS") | |
| 53 | |
| 54 | |
| 55 /******************** GLOBAL FLASH FILE SYSTEM CONTROL BLOCK ********************/ | |
| 56 /* */ | |
| 57 /* Define a global structure used to gather information related to the 'Global */ | |
| 58 /* Flash File System Control Block'. */ | |
| 59 typedef struct | |
| 60 { | |
| 61 BOOLEAN is_running; /* Indicates */ | |
| 62 /* whether the */ | |
| 63 /* Flash File */ | |
| 64 /* System is */ | |
| 65 /* running. */ | |
| 66 char current_working_dir[FFS_MAX_PATH_LENGTH]; /* Indicates the */ | |
| 67 /* current */ | |
| 68 /* working */ | |
| 69 /* directory. */ | |
| 70 } T_FFS_CTRL_BLK; | |
| 71 | |
| 72 | |
| 73 /******************** GLOBAL FLASH FILE SYSTEM CONTROL BLOCK ********************/ | |
| 74 /* */ | |
| 75 T_FFS_CTRL_BLK gbl_ffs_ctrl_blk; | |
| 76 | |
| 77 /* Define a pointer to the 'Global Flash File System Control Block'. */ | |
| 78 T_FFS_CTRL_BLK *gbl_ffs_ctrl_blk_p = NULL; | |
| 79 | |
| 80 | |
| 81 /********************************************************************************/ | |
| 82 /* */ | |
| 83 /* Function Name: ffs_init_working_folder */ | |
| 84 /* */ | |
| 85 /* Purpose: This function sets the working directory up. */ | |
| 86 /* */ | |
| 87 /* Input Parameter: None. */ | |
| 88 /* */ | |
| 89 /* Output Parameter: None. */ | |
| 90 /* */ | |
| 91 /* Global Parameter: */ | |
| 92 /* gbl_ffs_ctrl_blk_p - Points to the 'Global Flash File System Control */ | |
| 93 /* Block'. */ | |
| 94 /* */ | |
| 95 /* Note: None. */ | |
| 96 /* */ | |
| 97 /* Revision History: */ | |
| 98 /* 02/28/02 Pascal Pompei */ | |
| 99 /* - Create. */ | |
| 100 /* */ | |
| 101 /********************************************************************************/ | |
| 102 T_FFS_RET ffs_init_working_folder (void) | |
| 103 { | |
| 104 | |
| 105 /******************** ffs_init_working_folder function begins *******************/ | |
| 106 | |
| 107 /* First, check whether the current working directory matches the reference */ | |
| 108 /* one. Otherwise, create the reference directory. */ | |
| 109 | |
| 110 strcpy (gbl_ffs_ctrl_blk_p->current_working_dir, FFS_DIR); | |
| 111 | |
| 112 if ((CreateDirectory (TEXT(gbl_ffs_ctrl_blk_p->current_working_dir), \ | |
| 113 NULL) == FALSE) && \ | |
| 114 (GetLastError () != ERROR_ALREADY_EXISTS)) | |
| 115 { | |
| 116 return (EFFS_DRIVER); | |
| 117 } | |
| 118 | |
| 119 return (EFFS_OK); | |
| 120 | |
| 121 } /******************* End of ffs_init_working_folder function ******************/ | |
| 122 | |
| 123 | |
| 124 /********************************************************************************/ | |
| 125 /* */ | |
| 126 /* Function Name: ffs_is_valid_object_name */ | |
| 127 /* */ | |
| 128 /* Purpose: This function checks whether the name of an object is */ | |
| 129 /* valid, according to the Microsoft® Win32® Programmer's */ | |
| 130 /* Reference. */ | |
| 131 /* */ | |
| 132 /* Input Parameter: */ | |
| 133 /* object_name_p - Points to the name of the object to check */ | |
| 134 /* (0-terminated string). */ | |
| 135 /* */ | |
| 136 /* Output Parameter: None. */ | |
| 137 /* */ | |
| 138 /* Global Parameter: None. */ | |
| 139 /* */ | |
| 140 /* Note: None. */ | |
| 141 /* */ | |
| 142 /* Revision History: */ | |
| 143 /* 06/27/01 David Lamy-Charrier */ | |
| 144 /* - Create. */ | |
| 145 /* */ | |
| 146 /********************************************************************************/ | |
| 147 T_FFS_RET ffs_is_valid_object_name (const char *object_name_p) | |
| 148 { | |
| 149 /* Declare local variables. */ | |
| 150 DWORD object_count = 0x00000000; | |
| 151 DWORD path_count = 0x00000000; | |
| 152 | |
| 153 /******************* ffs_is_valid_object_name function begins *******************/ | |
| 154 | |
| 155 /* First, check for the leading '/' character. */ | |
| 156 if (object_name_p[path_count++] != '/') | |
| 157 { | |
| 158 return (EFFS_BADNAME); | |
| 159 } | |
| 160 | |
| 161 /* Then, check for invalid characters or too long object names. */ | |
| 162 for (; | |
| 163 path_count <= FFS_MAX_PATH_LENGTH; | |
| 164 path_count++) | |
| 165 { | |
| 166 | |
| 167 /* Check for invalid characters. */ | |
| 168 if (((object_name_p[path_count] >= 'a') && (object_name_p[path_count] <= 'z')) || \ | |
| 169 ((object_name_p[path_count] >= 'A') && (object_name_p[path_count] <= 'Z')) || \ | |
| 170 ((object_name_p[path_count] >= '0') && (object_name_p[path_count] <= '9')) || \ | |
| 171 (object_name_p[path_count] == '#') || \ | |
| 172 (object_name_p[path_count] == '$') || \ | |
| 173 (object_name_p[path_count] == '%') || \ | |
| 174 (object_name_p[path_count] == '+') || \ | |
| 175 (object_name_p[path_count] == '-') || \ | |
| 176 (object_name_p[path_count] == '.') || \ | |
| 177 (object_name_p[path_count] == '_')) | |
| 178 { | |
| 179 | |
| 180 /* Check for too long object names. */ | |
| 181 if (++object_count > FFS_MAX_OBJECT_LENGTH) | |
| 182 { | |
| 183 return (EFFS_NAMETOOLONG); | |
| 184 } | |
| 185 continue; | |
| 186 } | |
| 187 | |
| 188 /* Proceed with the next object name. */ | |
| 189 if (object_name_p[path_count] == '/') | |
| 190 { | |
| 191 | |
| 192 /* Check for empty object names. */ | |
| 193 if (object_count == 0x00000000) | |
| 194 { | |
| 195 break; | |
| 196 } | |
| 197 object_count = 0x00000000; | |
| 198 continue; | |
| 199 } | |
| 200 break; | |
| 201 } | |
| 202 | |
| 203 /* Check for the ending '/' character. */ | |
| 204 if ((object_name_p[path_count] == '\x00') && \ | |
| 205 (object_count == 0x00000000)) | |
| 206 { | |
| 207 return (EFFS_NOTADIR); | |
| 208 } | |
| 209 | |
| 210 /* Report an error whether an object name contains some illegal characters. */ | |
| 211 if ((object_name_p[path_count] != '\x00') || \ | |
| 212 (object_count == 0x00000000)) | |
| 213 { | |
| 214 return (EFFS_BADNAME); | |
| 215 } | |
| 216 return (EFFS_OK); | |
| 217 | |
| 218 } /****************** End of ffs_is_valid_object_name function ******************/ | |
| 219 | |
| 220 | |
| 221 /********************************************************************************/ | |
| 222 /* */ | |
| 223 /* Function Name: ffs_convert_to_win32_filename */ | |
| 224 /* */ | |
| 225 /* Purpose: This function converts filenames in accordance with */ | |
| 226 /* the Microsoft® Win32® Programmer's Reference. */ | |
| 227 /* */ | |
| 228 /* Input Parameter: */ | |
| 229 /* filename_p - Points to the filename to convert (0-terminated */ | |
| 230 /* string). */ | |
| 231 /* */ | |
| 232 /* Output Parameter: */ | |
| 233 /* win32_filename_p - Points to the filename as defined in the */ | |
| 234 /* Microsoft® Win32® Programmer's Reference. */ | |
| 235 /* */ | |
| 236 /* Global Parameter: */ | |
| 237 /* gbl_ffs_ctrl_blk_p - Points to the 'Global Flash File System Control */ | |
| 238 /* Block'. */ | |
| 239 /* */ | |
| 240 /* Note: None. */ | |
| 241 /* */ | |
| 242 /* Revision History: */ | |
| 243 /* 06/27/01 David Lamy-Charrier */ | |
| 244 /* - Create. */ | |
| 245 /* */ | |
| 246 /********************************************************************************/ | |
| 247 T_FFS_RET ffs_convert_to_win32_filename (const char *filename_p, | |
| 248 char win32_filename_p[FFS_MAX_PATH_LENGTH]) | |
| 249 { | |
| 250 /* Declare local variables. */ | |
| 251 DWORD filename_len = 0x00000000; | |
| 252 DWORD pathname_len = 0x00000000; | |
| 253 | |
| 254 /***************** ffs_convert_to_win32_filename function begins ****************/ | |
| 255 | |
| 256 /* Get the lengths of both filenames. */ | |
| 257 filename_len = strlen (filename_p); | |
| 258 pathname_len = strlen (gbl_ffs_ctrl_blk_p->current_working_dir); | |
| 259 | |
| 260 /* Convert the filename in accordance with the Microsoft® Win32® */ | |
| 261 /* Programmer's Reference. Abort whether the filename is too long. */ | |
| 262 if ((pathname_len + filename_len + 0x00000001) > FFS_MAX_PATH_LENGTH) | |
| 263 { | |
| 264 return (EFFS_NAMETOOLONG); | |
| 265 } | |
| 266 (void) memcpy (win32_filename_p, | |
| 267 gbl_ffs_ctrl_blk_p->current_working_dir, | |
| 268 pathname_len); | |
| 269 (void) memcpy (win32_filename_p + pathname_len, | |
| 270 filename_p, | |
| 271 filename_len); | |
| 272 win32_filename_p[pathname_len + filename_len] = '\x00'; | |
| 273 return (EFFS_OK); | |
| 274 | |
| 275 } /**************** End of ffs_convert_to_win32_filename function ***************/ | |
| 276 | |
| 277 | |
| 278 /********************************************************************************/ | |
| 279 /* */ | |
| 280 /* Function Name: ffs_open */ | |
| 281 /* */ | |
| 282 /* Purpose: This function opens or creates a file. */ | |
| 283 /* */ | |
| 284 /* Input Parameters: */ | |
| 285 /* pathname_p - Points to the name of the file to open or create */ | |
| 286 /* (0-terminated string). */ | |
| 287 /* flags - Specifies the modes used to open the file. */ | |
| 288 /* */ | |
| 289 /* Output Parameter: None. */ | |
| 290 /* */ | |
| 291 /* Global Parameter: */ | |
| 292 /* gbl_ffs_ctrl_blk_p - Points to the 'Global Flash File System Control */ | |
| 293 /* Block'. */ | |
| 294 /* */ | |
| 295 /* Note: The append concept while opening files is not */ | |
| 296 /* supported, according to the Microsoft® Win32® */ | |
| 297 /* Programmer's Reference. */ | |
| 298 /* */ | |
| 299 /* Revision History: */ | |
| 300 /* 06/27/01 David Lamy-Charrier */ | |
| 301 /* - Create. */ | |
| 302 /* */ | |
| 303 /********************************************************************************/ | |
| 304 T_FFS_FD ffs_open (const char *pathname_p, | |
| 305 T_FFS_OPEN_FLAGS flags) | |
| 306 { | |
| 307 /* Declare local variables. */ | |
| 308 char win32_pathname_p[FFS_MAX_PATH_LENGTH] = ""; | |
| 309 DWORD desired_access = GENERIC_WRITE; | |
| 310 DWORD creation_distribution = OPEN_EXISTING; | |
| 311 HANDLE handle = INVALID_HANDLE_VALUE; | |
| 312 T_FFS_IFD ifd = {0x00000000}; | |
| 313 T_FFS_RET return_status = EFFS_OK; | |
| 314 | |
| 315 /*************************** ffs_open function begins ***************************/ | |
| 316 | |
| 317 /* First, check whether the Flash File System is running. */ | |
| 318 if ((gbl_ffs_ctrl_blk_p == NULL) || (gbl_ffs_ctrl_blk_p->is_running == FALSE)) | |
| 319 { | |
| 320 return (EFFS_AGAIN); | |
| 321 } | |
| 322 | |
| 323 /* Then, convert the filename as defined in the Microsoft® Win32® */ | |
| 324 /* Programmer's Reference. Abort whether any error occurred. */ | |
| 325 if (((return_status = ffs_is_valid_object_name (pathname_p)) != EFFS_OK) || \ | |
| 326 ((return_status = ffs_convert_to_win32_filename (pathname_p, \ | |
| 327 win32_pathname_p)) != EFFS_OK)) | |
| 328 { | |
| 329 return (return_status); | |
| 330 } | |
| 331 | |
| 332 /* Convert flags as defined in the Microsoft® Win32® Programmer's */ | |
| 333 /* Reference. */ | |
| 334 switch (flags & FFS_O_RDWR) | |
| 335 { | |
| 336 | |
| 337 /* The file is opened as 'read-only'. */ | |
| 338 case FFS_O_RDONLY: | |
| 339 { | |
| 340 | |
| 341 /* 'Read-only' must not be combined with any other options. */ | |
| 342 if (flags != FFS_O_RDONLY) | |
| 343 { | |
| 344 return (EFFS_INVALID); | |
| 345 } | |
| 346 desired_access = GENERIC_READ; | |
| 347 break; | |
| 348 } | |
| 349 | |
| 350 /* The file is opened as 'read-write'. */ | |
| 351 case FFS_O_RDWR: | |
| 352 { | |
| 353 desired_access |= GENERIC_READ; | |
| 354 } | |
| 355 | |
| 356 /* The file is opened as 'write-only'. */ | |
| 357 case FFS_O_WRONLY: | |
| 358 { | |
| 359 switch (flags & ~FFS_O_RDWR) | |
| 360 { | |
| 361 | |
| 362 /* Create the file if it does not exist, otherwise truncate */ | |
| 363 /* it. */ | |
| 364 case (FFS_O_CREATE | FFS_O_APPEND | FFS_O_TRUNC): | |
| 365 { | |
| 366 (ifd.ifd).append = TRUE; | |
| 367 } | |
| 368 case (FFS_O_CREATE | FFS_O_TRUNC): | |
| 369 { | |
| 370 creation_distribution = CREATE_ALWAYS; | |
| 371 break; | |
| 372 } | |
| 373 | |
| 374 /* Create the file if it does not exist, otherwise open it */ | |
| 375 /* for appending. */ | |
| 376 case (FFS_O_CREATE | FFS_O_APPEND): | |
| 377 { | |
| 378 (ifd.ifd).append = TRUE; | |
| 379 creation_distribution = OPEN_ALWAYS; | |
| 380 break; | |
| 381 } | |
| 382 | |
| 383 /* Create the file if it does not exist, otherwise the */ | |
| 384 /* function fails. */ | |
| 385 case (FFS_O_CREATE | FFS_O_EXCL): | |
| 386 { | |
| 387 creation_distribution = CREATE_NEW; | |
| 388 break; | |
| 389 } | |
| 390 | |
| 391 /* Create the file if it does not exist, otherwise open it. */ | |
| 392 case FFS_O_CREATE: | |
| 393 { | |
| 394 creation_distribution = OPEN_ALWAYS; | |
| 395 break; | |
| 396 } | |
| 397 | |
| 398 /* Truncate the file if it already exists, otherwise the */ | |
| 399 /* function fails. */ | |
| 400 case (FFS_O_APPEND | FFS_O_TRUNC): | |
| 401 { | |
| 402 (ifd.ifd).append = TRUE; | |
| 403 } | |
| 404 case FFS_O_TRUNC: | |
| 405 { | |
| 406 creation_distribution = TRUNCATE_EXISTING; | |
| 407 break; | |
| 408 } | |
| 409 | |
| 410 /* Open the file for appending if it already exists, */ | |
| 411 /* otherwise the function fails. */ | |
| 412 case FFS_O_APPEND: | |
| 413 { | |
| 414 (ifd.ifd).append = TRUE; | |
| 415 break; | |
| 416 } | |
| 417 default: | |
| 418 { | |
| 419 break; | |
| 420 } | |
| 421 } | |
| 422 break; | |
| 423 } | |
| 424 default: | |
| 425 { | |
| 426 return (EFFS_INVALID); | |
| 427 } | |
| 428 } | |
| 429 | |
| 430 /* Open/create the file as specified. */ | |
| 431 if (((handle = CreateFile (win32_pathname_p, \ | |
| 432 desired_access, \ | |
| 433 0x0000, \ | |
| 434 NULL, \ | |
| 435 creation_distribution, \ | |
| 436 FILE_ATTRIBUTE_NORMAL, \ | |
| 437 NULL)) == INVALID_HANDLE_VALUE) || \ | |
| 438 (((ifd.ifd).append) && \ | |
| 439 (SetFilePointer (handle, \ | |
| 440 0x00000000, \ | |
| 441 NULL, \ | |
| 442 FILE_END) == 0xFFFFFFFF))) | |
| 443 { | |
| 444 | |
| 445 /* Declare a local block variable. */ | |
| 446 DWORD error = NO_ERROR; | |
| 447 | |
| 448 /* Get the error code. */ | |
| 449 error = GetLastError (); | |
| 450 | |
| 451 /* If the file handle is valid, then close the file first. */ | |
| 452 if (handle != INVALID_HANDLE_VALUE) | |
| 453 { | |
| 454 (void) CloseHandle (handle); | |
| 455 } | |
| 456 switch (error) | |
| 457 { | |
| 458 | |
| 459 /* Unable to create a file when it already exists. */ | |
| 460 case ERROR_ALREADY_EXISTS: | |
| 461 | |
| 462 /* The file exists. */ | |
| 463 case ERROR_FILE_EXISTS: | |
| 464 { | |
| 465 return (EFFS_EXISTS); | |
| 466 } | |
| 467 | |
| 468 /* The directory name is invalid. */ | |
| 469 case ERROR_DIRECTORY: | |
| 470 | |
| 471 /* Unable to find the file specified. */ | |
| 472 case ERROR_FILE_NOT_FOUND: | |
| 473 { | |
| 474 return (EFFS_NOTFOUND); | |
| 475 } | |
| 476 | |
| 477 /* Unable to open the file because too many files are currently */ | |
| 478 /* open. */ | |
| 479 case ERROR_TOO_MANY_OPEN_FILES: | |
| 480 { | |
| 481 return (EFFS_NUMFD); | |
| 482 } | |
| 483 | |
| 484 /* The disk is full. */ | |
| 485 case ERROR_HANDLE_DISK_FULL: | |
| 486 { | |
| 487 return (EFFS_FSFULL); | |
| 488 } | |
| 489 | |
| 490 /* The filename or directory name is syntactically incorrect. */ | |
| 491 case ERROR_INVALID_NAME: | |
| 492 { | |
| 493 return (EFFS_BADNAME); | |
| 494 } | |
| 495 default: | |
| 496 { | |
| 497 return (EFFS_DRIVER); | |
| 498 } | |
| 499 } | |
| 500 } | |
| 501 | |
| 502 /* If the file handle is invalid, then close the file. */ | |
| 503 if (((INT32) (handle)) & 0xC0000000) | |
| 504 { | |
| 505 (void) CloseHandle (handle); | |
| 506 return (EFFS_NUMFD); | |
| 507 } | |
| 508 | |
| 509 /* Get the file handle. */ | |
| 510 ifd.fd |= (INT32) (handle); | |
| 511 return ((T_FFS_FD) (ifd.fd)); | |
| 512 | |
| 513 } /************************** End of ffs_open function **************************/ | |
| 514 | |
| 515 | |
| 516 /********************************************************************************/ | |
| 517 /* */ | |
| 518 /* Function Name: ffs_close */ | |
| 519 /* */ | |
| 520 /* Purpose: This function closes an open file. */ | |
| 521 /* */ | |
| 522 /* Input Parameter: */ | |
| 523 /* fd - Specifies the file descriptor associated with the */ | |
| 524 /* file to close. */ | |
| 525 /* */ | |
| 526 /* Output Parameter: None. */ | |
| 527 /* */ | |
| 528 /* Global Parameter: */ | |
| 529 /* gbl_ffs_ctrl_blk_p - Points to the 'Global Flash File System Control */ | |
| 530 /* Block'. */ | |
| 531 /* */ | |
| 532 /* Note: None. */ | |
| 533 /* */ | |
| 534 /* Revision History: */ | |
| 535 /* 06/27/01 David Lamy-Charrier */ | |
| 536 /* - Create. */ | |
| 537 /* */ | |
| 538 /********************************************************************************/ | |
| 539 T_FFS_RET ffs_close (T_FFS_FD fd) | |
| 540 { | |
| 541 /* Declare a local variable. */ | |
| 542 T_FFS_IFD ifd = {0x00000000}; | |
| 543 | |
| 544 /*************************** ffs_close function begins **************************/ | |
| 545 | |
| 546 /* First, check whether the Flash File System is running. */ | |
| 547 if ((gbl_ffs_ctrl_blk_p == NULL) || (gbl_ffs_ctrl_blk_p->is_running == FALSE)) | |
| 548 { | |
| 549 return (EFFS_AGAIN); | |
| 550 } | |
| 551 | |
| 552 /* Then, get the file handle. */ | |
| 553 ifd.fd = fd; | |
| 554 | |
| 555 /* At last, close the file. */ | |
| 556 if (CloseHandle ((HANDLE) ((ifd.ifd).handle)) == FALSE) | |
| 557 { | |
| 558 return (EFFS_BADFD); | |
| 559 } | |
| 560 return (EFFS_OK); | |
| 561 | |
| 562 } /************************** End of ffs_close function *************************/ | |
| 563 | |
| 564 | |
| 565 /********************************************************************************/ | |
| 566 /* */ | |
| 567 /* Function Name: ffs_write */ | |
| 568 /* */ | |
| 569 /* Purpose: This function writes data to an open file. */ | |
| 570 /* */ | |
| 571 /* Input Parameters: */ | |
| 572 /* fd - Specifies the file descriptor associated with the */ | |
| 573 /* open file. */ | |
| 574 /* buffer_p - Points to the buffer containing the data to be */ | |
| 575 /* written to the file. */ | |
| 576 /* size - Specifies the number of bytes to write to the */ | |
| 577 /* file. */ | |
| 578 /* */ | |
| 579 /* Output Parameter: None. */ | |
| 580 /* */ | |
| 581 /* Global Parameter: */ | |
| 582 /* gbl_ffs_ctrl_blk_p - Points to the 'Global Flash File System Control */ | |
| 583 /* Block'. */ | |
| 584 /* */ | |
| 585 /* Note: This function is not responsible for (de)allocating */ | |
| 586 /* the buffer containing the data to be written to the */ | |
| 587 /* file. */ | |
| 588 /* */ | |
| 589 /* Revision History: */ | |
| 590 /* 06/29/01 David Lamy-Charrier */ | |
| 591 /* - Create. */ | |
| 592 /* */ | |
| 593 /********************************************************************************/ | |
| 594 T_FFS_SIZE ffs_write (T_FFS_FD fd, | |
| 595 void *buffer_p, | |
| 596 T_FFS_SIZE size) | |
| 597 { | |
| 598 /* Declare local variables. */ | |
| 599 DWORD bytes_written = 0x00000000; | |
| 600 T_FFS_IFD ifd = {0x00000000}; | |
| 601 | |
| 602 /*************************** ffs_write function begins **************************/ | |
| 603 | |
| 604 /* First, check whether the Flash File System is running. */ | |
| 605 if ((gbl_ffs_ctrl_blk_p == NULL) || (gbl_ffs_ctrl_blk_p->is_running == FALSE)) | |
| 606 { | |
| 607 return (EFFS_AGAIN); | |
| 608 } | |
| 609 | |
| 610 /* Then, get the file handle. */ | |
| 611 ifd.fd = fd; | |
| 612 | |
| 613 /* Then, check whether the file is opened for appending. Indeed, opening a */ | |
| 614 /* file with append mode shall cause all subsequent writes to the file to */ | |
| 615 /* be forced to end-of-file (EOF) position, regardless of intervening calls */ | |
| 616 /* to ffs_seek (). */ | |
| 617 if (((ifd.ifd).append) && \ | |
| 618 (SetFilePointer ((HANDLE) ((ifd.ifd).handle), \ | |
| 619 0x00000000, \ | |
| 620 NULL, \ | |
| 621 FILE_END) == 0xFFFFFFFF)) | |
| 622 { | |
| 623 return (EFFS_BADFD); | |
| 624 } | |
| 625 | |
| 626 /* At last, write data to the file. */ | |
| 627 if (WriteFile ((HANDLE) ((ifd.ifd).handle), \ | |
| 628 buffer_p, \ | |
| 629 size, \ | |
| 630 &bytes_written, \ | |
| 631 NULL) == FALSE) | |
| 632 { | |
| 633 | |
| 634 /* Get the error code. */ | |
| 635 switch (GetLastError ()) | |
| 636 { | |
| 637 | |
| 638 /* Access denied. */ | |
| 639 case ERROR_ACCESS_DENIED: | |
| 640 { | |
| 641 return (EFFS_BADOP); | |
| 642 } | |
| 643 | |
| 644 /* The disk is full. */ | |
| 645 case ERROR_HANDLE_DISK_FULL: | |
| 646 { | |
| 647 return (EFFS_NOSPACE); | |
| 648 } | |
| 649 default: | |
| 650 { | |
| 651 return (EFFS_BADFD); | |
| 652 } | |
| 653 } | |
| 654 } | |
| 655 return (bytes_written); | |
| 656 | |
| 657 } /************************** End of ffs_write function *************************/ | |
| 658 | |
| 659 | |
| 660 /********************************************************************************/ | |
| 661 /* */ | |
| 662 /* Function Name: ffs_read */ | |
| 663 /* */ | |
| 664 /* Purpose: This function reads data from an open file. */ | |
| 665 /* */ | |
| 666 /* Input Parameters: */ | |
| 667 /* fd - Specifies the file descriptor associated with the */ | |
| 668 /* open file. */ | |
| 669 /* buffer_p - Points to the buffer that receives the data read */ | |
| 670 /* from the file. */ | |
| 671 /* size - Specifies the number of bytes to be read from the */ | |
| 672 /* file. */ | |
| 673 /* */ | |
| 674 /* Output Parameter: None. */ | |
| 675 /* */ | |
| 676 /* Global Parameter: */ | |
| 677 /* gbl_ffs_ctrl_blk_p - Points to the 'Global Flash File System Control */ | |
| 678 /* Block'. */ | |
| 679 /* */ | |
| 680 /* Note: This function is not responsible for (de)allocating */ | |
| 681 /* the buffer that receives the data read from the file. */ | |
| 682 /* */ | |
| 683 /* Revision History: */ | |
| 684 /* 06/29/01 David Lamy-Charrier */ | |
| 685 /* - Create. */ | |
| 686 /* */ | |
| 687 /********************************************************************************/ | |
| 688 T_FFS_SIZE ffs_read (T_FFS_FD fd, | |
| 689 void *buffer_p, | |
| 690 T_FFS_SIZE size) | |
| 691 { | |
| 692 /* Declare local variables. */ | |
| 693 DWORD bytes_read = 0x00000000; | |
| 694 T_FFS_IFD ifd = {0x00000000}; | |
| 695 | |
| 696 /*************************** ffs_read function begins ***************************/ | |
| 697 | |
| 698 /* First, check whether the Flash File System is running. */ | |
| 699 if ((gbl_ffs_ctrl_blk_p == NULL) || (gbl_ffs_ctrl_blk_p->is_running == FALSE)) | |
| 700 { | |
| 701 return (EFFS_AGAIN); | |
| 702 } | |
| 703 | |
| 704 /* Then, get the file handle. */ | |
| 705 ifd.fd = fd; | |
| 706 | |
| 707 /* At last, read data from the file. */ | |
| 708 if (ReadFile ((HANDLE) ((ifd.ifd).handle), \ | |
| 709 buffer_p, \ | |
| 710 size, \ | |
| 711 &bytes_read, \ | |
| 712 NULL) == FALSE) | |
| 713 { | |
| 714 return (EFFS_BADFD); | |
| 715 } | |
| 716 return (bytes_read); | |
| 717 | |
| 718 } /************************** End of ffs_read function **************************/ | |
| 719 | |
| 720 | |
| 721 /********************************************************************************/ | |
| 722 /* */ | |
| 723 /* Function Name: ffs_seek */ | |
| 724 /* */ | |
| 725 /* Purpose: This function moves the file pointer of an open file. */ | |
| 726 /* */ | |
| 727 /* Input Parameters: */ | |
| 728 /* fd - Specifies the file descriptor associated with the */ | |
| 729 /* open file. */ | |
| 730 /* offset - Specifies the number of bytes to move file */ | |
| 731 /* pointer. */ | |
| 732 /* whence - Specifies the starting point for the file pointer */ | |
| 733 /* move. */ | |
| 734 /* */ | |
| 735 /* Output Parameter: None. */ | |
| 736 /* */ | |
| 737 /* Global Parameter: */ | |
| 738 /* gbl_ffs_ctrl_blk_p - Points to the 'Global Flash File System Control */ | |
| 739 /* Block'. */ | |
| 740 /* */ | |
| 741 /* Note: This function does not allow the file pointer to be */ | |
| 742 /* set beyond the end-of-file (EOF) position, in contrary */ | |
| 743 /* to the Microsoft® Win32® Programmer's Reference. */ | |
| 744 /* */ | |
| 745 /* Revision History: */ | |
| 746 /* 06/29/01 David Lamy-Charrier */ | |
| 747 /* - Create. */ | |
| 748 /* */ | |
| 749 /********************************************************************************/ | |
| 750 T_FFS_SIZE ffs_seek (T_FFS_FD fd, | |
| 751 T_FFS_SIZE offset, | |
| 752 T_FFS_WHENCE whence) | |
| 753 { | |
| 754 /* Declare local variables. */ | |
| 755 DWORD file_size = 0x00000000; | |
| 756 DWORD new_file_pointer = 0x00000000; | |
| 757 T_FFS_IFD ifd = {0x00000000}; | |
| 758 | |
| 759 /*************************** ffs_seek function begins ***************************/ | |
| 760 | |
| 761 /* First, check whether the Flash File System is running. */ | |
| 762 if ((gbl_ffs_ctrl_blk_p == NULL) || (gbl_ffs_ctrl_blk_p->is_running == FALSE)) | |
| 763 { | |
| 764 return (EFFS_AGAIN); | |
| 765 } | |
| 766 | |
| 767 /* Then, get the file handle. */ | |
| 768 ifd.fd = fd; | |
| 769 | |
| 770 /* At last, move the file pointer and get the size of the file. */ | |
| 771 if (((new_file_pointer = SetFilePointer ((HANDLE) ((ifd.ifd).handle), \ | |
| 772 offset, \ | |
| 773 NULL, \ | |
| 774 whence)) != 0xFFFFFFFF) && \ | |
| 775 ((file_size = GetFileSize ((HANDLE) ((ifd.ifd).handle), \ | |
| 776 NULL)) != 0xFFFFFFFF)) | |
| 777 { | |
| 778 | |
| 779 /* Check whether the file pointer is beyond the end-of-file (EOF) */ | |
| 780 /* position. */ | |
| 781 if (new_file_pointer <= file_size) | |
| 782 { | |
| 783 return (new_file_pointer); | |
| 784 } | |
| 785 | |
| 786 /* In such a case, back to the former position. */ | |
| 787 if (SetFilePointer ((HANDLE) ((ifd.ifd).handle), \ | |
| 788 -offset, \ | |
| 789 NULL, \ | |
| 790 FILE_CURRENT) != 0xFFFFFFFF) | |
| 791 { | |
| 792 return (EFFS_INVALID); | |
| 793 } | |
| 794 } | |
| 795 | |
| 796 /* Get the error code. */ | |
| 797 switch (GetLastError ()) | |
| 798 { | |
| 799 | |
| 800 /* Invalid parameters. */ | |
| 801 case ERROR_INVALID_PARAMETER: | |
| 802 | |
| 803 /* Unable to move the file pointer before the beginning of the file. */ | |
| 804 case ERROR_NEGATIVE_SEEK: | |
| 805 | |
| 806 /* Unable to set the file pointer on the specified file. */ | |
| 807 case ERROR_SEEK_ON_DEVICE: | |
| 808 { | |
| 809 return (EFFS_INVALID); | |
| 810 } | |
| 811 default: | |
| 812 { | |
| 813 break; | |
| 814 } | |
| 815 } | |
| 816 return (EFFS_BADFD); | |
| 817 | |
| 818 } /************************** End of ffs_seek function **************************/ | |
| 819 | |
| 820 | |
| 821 /********************************************************************************/ | |
| 822 /* */ | |
| 823 /* Function Name: ffs_ftruncate */ | |
| 824 /* */ | |
| 825 /* Purpose: This function truncates an open file by moving the */ | |
| 826 /* end-of-file (EOF) position. */ | |
| 827 /* */ | |
| 828 /* Input Parameters: */ | |
| 829 /* fd - Specifies the file descriptor associated with the */ | |
| 830 /* open file. */ | |
| 831 /* length - Specifies the number of bytes to move file */ | |
| 832 /* pointer. */ | |
| 833 /* */ | |
| 834 /* Output Parameter: None. */ | |
| 835 /* */ | |
| 836 /* Global Parameter: */ | |
| 837 /* gbl_ffs_ctrl_blk_p - Points to the 'Global Flash File System Control */ | |
| 838 /* Block'. */ | |
| 839 /* */ | |
| 840 /* Note: This function does not allow the file pointer to be */ | |
| 841 /* set beyond the end-of-file (EOF) position, in contrary */ | |
| 842 /* to the Microsoft® Win32® Programmer's Reference. */ | |
| 843 /* */ | |
| 844 /* Revision History: */ | |
| 845 /* 02/13/02 Pascal Pompei */ | |
| 846 /* - Create. */ | |
| 847 /* */ | |
| 848 /********************************************************************************/ | |
| 849 T_FFS_RET ffs_ftruncate (T_FFS_FD fd, | |
| 850 T_FFS_OFFSET length) | |
| 851 { | |
| 852 /* Declare a local variable. */ | |
| 853 T_FFS_IFD ifd = {0x00000000}; | |
| 854 | |
| 855 /************************* ffs_ftruncate function begins ************************/ | |
| 856 | |
| 857 /* First, check whether the size is greater than the current file pointer */ | |
| 858 /* position. */ | |
| 859 if (length < (T_FFS_OFFSET) (ffs_seek (fd, \ | |
| 860 0, \ | |
| 861 FFS_SEEK_CUR))) | |
| 862 { | |
| 863 return (EFFS_INVALID); | |
| 864 } | |
| 865 | |
| 866 /* Move the end-of-file (EOF) position. */ | |
| 867 switch (ffs_seek (fd, \ | |
| 868 length, \ | |
| 869 FFS_SEEK_SET)) | |
| 870 { | |
| 871 | |
| 872 /* Unable to move the file pointer beyond the end-of-file (EOF) */ | |
| 873 /* position. */ | |
| 874 case EFFS_INVALID: | |
| 875 { | |
| 876 return (EFFS_OK); | |
| 877 } | |
| 878 | |
| 879 /* File not found. */ | |
| 880 case EFFS_BADFD: | |
| 881 { | |
| 882 return (EFFS_BADFD); | |
| 883 } | |
| 884 default: | |
| 885 { | |
| 886 break; | |
| 887 } | |
| 888 } | |
| 889 | |
| 890 /* Then, get the file handle. */ | |
| 891 ifd.fd = fd; | |
| 892 | |
| 893 /* At last, set the current file pointer as the end-of-file (EOF) position. */ | |
| 894 if (SetEndOfFile ((HANDLE) ((ifd.ifd).handle)) == FALSE) | |
| 895 { | |
| 896 return (EFFS_INVALID); | |
| 897 } | |
| 898 return (EFFS_OK); | |
| 899 | |
| 900 } /************************ End of ffs_ftruncate function ***********************/ | |
| 901 | |
| 902 | |
| 903 /********************************************************************************/ | |
| 904 /* */ | |
| 905 /* Function Name: ffs_stat */ | |
| 906 /* */ | |
| 907 /* Purpose: This function gets information (meta-data) about a */ | |
| 908 /* object. */ | |
| 909 /* */ | |
| 910 /* Input Parameter: */ | |
| 911 /* pathname_p - Points to the name of the file or directory */ | |
| 912 /* (0-terminated string). */ | |
| 913 /* */ | |
| 914 /* Output Parameter: */ | |
| 915 /* stat_p - Points to information (meta-data) about the */ | |
| 916 /* object. */ | |
| 917 /* */ | |
| 918 /* Global Parameter: */ | |
| 919 /* gbl_ffs_ctrl_blk_p - Points to the 'Global Flash File System Control */ | |
| 920 /* Block'. */ | |
| 921 /* */ | |
| 922 /* Note: None. */ | |
| 923 /* */ | |
| 924 /* Revision History: */ | |
| 925 /* 02/28/01 Pascal Pompei */ | |
| 926 /* - Create. */ | |
| 927 /* */ | |
| 928 /********************************************************************************/ | |
| 929 T_FFS_RET ffs_stat (const char *pathname_p, | |
| 930 T_FFS_STAT *stat_p) | |
| 931 { | |
| 932 /* Declare local variables. */ | |
| 933 char win32_pathname_p[FFS_MAX_PATH_LENGTH] = ""; | |
| 934 HANDLE search_handle = INVALID_HANDLE_VALUE; | |
| 935 T_FFS_RET return_status = EFFS_OK; | |
| 936 WIN32_FIND_DATA find_data; | |
| 937 | |
| 938 /*************************** ffs_stat function begins ***************************/ | |
| 939 | |
| 940 /* First, check whether the Flash File System is running. */ | |
| 941 if ((gbl_ffs_ctrl_blk_p == NULL) || (gbl_ffs_ctrl_blk_p->is_running == FALSE)) | |
| 942 { | |
| 943 return (EFFS_AGAIN); | |
| 944 } | |
| 945 | |
| 946 /* Then, convert the name of the file or the directory as defined in the */ | |
| 947 /* Microsoft® Win32® Programmer's Reference. Abort whether any error */ | |
| 948 /* occurred. */ | |
| 949 if (((return_status = ffs_is_valid_object_name (pathname_p)) != EFFS_OK) || \ | |
| 950 ((return_status = ffs_convert_to_win32_filename (pathname_p, \ | |
| 951 win32_pathname_p)) != EFFS_OK)) | |
| 952 { | |
| 953 return (return_status); | |
| 954 } | |
| 955 | |
| 956 /* Search for a file or a directory whose name matches the specified one. */ | |
| 957 /* Abort whether the file or directory does not exist. */ | |
| 958 if (((search_handle = FindFirstFile (win32_pathname_p, \ | |
| 959 &find_data)) != INVALID_HANDLE_VALUE) && \ | |
| 960 (find_data.dwFileAttributes != 0xFFFFFFFF)) | |
| 961 { | |
| 962 | |
| 963 /* Get information depending on attributes for the the file or */ | |
| 964 /* directory. */ | |
| 965 if (find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) | |
| 966 { | |
| 967 stat_p->type = OT_DIR; | |
| 968 stat_p->size = 0x00000000; | |
| 969 } | |
| 970 else | |
| 971 { | |
| 972 stat_p->type = OT_FILE; | |
| 973 stat_p->size = find_data.nFileSizeLow; | |
| 974 } | |
| 975 | |
| 976 /* Close the search handle. */ | |
| 977 (void) FindClose (search_handle); | |
| 978 return (EFFS_OK); | |
| 979 } | |
| 980 return (EFFS_NOTFOUND); | |
| 981 | |
| 982 } /************************** End of ffs_stat function **************************/ | |
| 983 | |
| 984 | |
| 985 /********************************************************************************/ | |
| 986 /* */ | |
| 987 /* Function Name: ffs_remove */ | |
| 988 /* */ | |
| 989 /* Purpose: This function removes a file or a directory. */ | |
| 990 /* */ | |
| 991 /* Input Parameter: */ | |
| 992 /* pathname_p - Points to the name of the file or directory to */ | |
| 993 /* remove (0-terminated string). */ | |
| 994 /* */ | |
| 995 /* Output Parameter: None. */ | |
| 996 /* */ | |
| 997 /* Global Parameter: */ | |
| 998 /* gbl_ffs_ctrl_blk_p - Points to the 'Global Flash File System Control */ | |
| 999 /* Block'. */ | |
| 1000 /* */ | |
| 1001 /* Note: The variable callback_p is a pointer to a function */ | |
| 1002 /* that follows the C Calling Convention. However, such a */ | |
| 1003 /* variable has to be redefined as a pointer to a */ | |
| 1004 /* function that follows the Standard Calling Convention */ | |
| 1005 /* by using _stdcall (avoid 'error C2152: '=' : pointers */ | |
| 1006 /* to functions with different attributes' error */ | |
| 1007 /* message). */ | |
| 1008 /* */ | |
| 1009 /* Revision History: */ | |
| 1010 /* 06/29/01 David Lamy-Charrier */ | |
| 1011 /* - Create. */ | |
| 1012 /* */ | |
| 1013 /********************************************************************************/ | |
| 1014 T_FFS_RET ffs_remove (const char *pathname_p) | |
| 1015 { | |
| 1016 /* Declare local variables. */ | |
| 1017 BOOL (_stdcall *callback_p) (LPCTSTR) = DeleteFile; | |
| 1018 char win32_pathname_p[FFS_MAX_PATH_LENGTH] = ""; | |
| 1019 DWORD attributes = 0xFFFFFFFF; | |
| 1020 T_FFS_RET return_status = EFFS_OK; | |
| 1021 | |
| 1022 /************************** ffs_remove function begins **************************/ | |
| 1023 | |
| 1024 /* First, check whether the Flash File System is running. */ | |
| 1025 if ((gbl_ffs_ctrl_blk_p == NULL) || (gbl_ffs_ctrl_blk_p->is_running == FALSE)) | |
| 1026 { | |
| 1027 return (EFFS_AGAIN); | |
| 1028 } | |
| 1029 | |
| 1030 /* Then, convert the name of the file or the directory as defined in the */ | |
| 1031 /* Microsoft® Win32® Programmer's Reference. Abort whether any error */ | |
| 1032 /* occurred. */ | |
| 1033 if (((return_status = ffs_is_valid_object_name (pathname_p)) != EFFS_OK) || \ | |
| 1034 ((return_status = ffs_convert_to_win32_filename (pathname_p, \ | |
| 1035 win32_pathname_p)) != EFFS_OK)) | |
| 1036 { | |
| 1037 return (return_status); | |
| 1038 } | |
| 1039 | |
| 1040 /* Get attributes for the specified file or directory. */ | |
| 1041 if ((attributes = GetFileAttributes (win32_pathname_p)) == 0xFFFFFFFF) | |
| 1042 { | |
| 1043 return (EFFS_NOTFOUND); | |
| 1044 } | |
| 1045 | |
| 1046 /* Check whether the object is a directory. */ | |
| 1047 if (attributes & FILE_ATTRIBUTE_DIRECTORY) | |
| 1048 { | |
| 1049 callback_p = RemoveDirectory; | |
| 1050 } | |
| 1051 | |
| 1052 /* Remove the file or the directory. */ | |
| 1053 if ((*callback_p) (win32_pathname_p) == FALSE) | |
| 1054 { | |
| 1055 | |
| 1056 /* Get the error code. */ | |
| 1057 switch (GetLastError ()) | |
| 1058 { | |
| 1059 | |
| 1060 /* Access denied. */ | |
| 1061 case ERROR_ACCESS_DENIED: | |
| 1062 | |
| 1063 /* Unable to access the file because it is being used by another */ | |
| 1064 /* process. */ | |
| 1065 case ERROR_SHARING_VIOLATION: | |
| 1066 { | |
| 1067 return (EFFS_LOCKED); | |
| 1068 } | |
| 1069 | |
| 1070 /* The directory is not empty. */ | |
| 1071 case ERROR_DIR_NOT_EMPTY: | |
| 1072 { | |
| 1073 return (EFFS_DIRNOTEMPTY); | |
| 1074 } | |
| 1075 default: | |
| 1076 { | |
| 1077 return (EFFS_DRIVER); | |
| 1078 } | |
| 1079 } | |
| 1080 } | |
| 1081 return (EFFS_OK); | |
| 1082 | |
| 1083 } /************************* End of ffs_remove function *************************/ | |
| 1084 | |
| 1085 | |
| 1086 /********************************************************************************/ | |
| 1087 /* */ | |
| 1088 /* Function Name: ffs_mkdir */ | |
| 1089 /* */ | |
| 1090 /* Purpose: This function creates a new directory. */ | |
| 1091 /* */ | |
| 1092 /* Input Parameter: */ | |
| 1093 /* pathname_p - Points to the name of the directory to create */ | |
| 1094 /* (0-terminated string). */ | |
| 1095 /* */ | |
| 1096 /* Output Parameter: None. */ | |
| 1097 /* */ | |
| 1098 /* Global Parameter: */ | |
| 1099 /* gbl_ffs_ctrl_blk_p - Points to the 'Global Flash File System Control */ | |
| 1100 /* Block'. */ | |
| 1101 /* */ | |
| 1102 /* Note: None. */ | |
| 1103 /* */ | |
| 1104 /* Revision History: */ | |
| 1105 /* 06/29/01 David Lamy-Charrier */ | |
| 1106 /* - Create. */ | |
| 1107 /* */ | |
| 1108 /********************************************************************************/ | |
| 1109 T_FFS_RET ffs_mkdir (const char *pathname_p) | |
| 1110 { | |
| 1111 /* Declare local variables. */ | |
| 1112 char *object_name_p = NULL; | |
| 1113 char pathname_parsed_p[FFS_MAX_PATH_LENGTH] = ""; | |
| 1114 char win32_pathname_p[FFS_MAX_PATH_LENGTH] = ""; | |
| 1115 DWORD dir_nesting_depth = 0x00000000; | |
| 1116 T_FFS_RET return_status = EFFS_OK; | |
| 1117 | |
| 1118 /*************************** ffs_mkdir function begins **************************/ | |
| 1119 | |
| 1120 /* First, check whether the Flash File System is running. */ | |
| 1121 if ((gbl_ffs_ctrl_blk_p == NULL) || (gbl_ffs_ctrl_blk_p->is_running == FALSE)) | |
| 1122 { | |
| 1123 return (EFFS_AGAIN); | |
| 1124 } | |
| 1125 | |
| 1126 /* Then, convert the name of the directory as defined in the Microsoft® */ | |
| 1127 /* Win32® Programmer's Reference. Abort whether any error occurred. */ | |
| 1128 if (((return_status = ffs_is_valid_object_name (pathname_p)) != EFFS_OK) || \ | |
| 1129 ((return_status = ffs_convert_to_win32_filename (pathname_p, \ | |
| 1130 win32_pathname_p)) != EFFS_OK)) | |
| 1131 { | |
| 1132 return (return_status); | |
| 1133 } | |
| 1134 | |
| 1135 /* At last, check whether the directory nesting depth is exceeded. Thus, */ | |
| 1136 /* search for '/' characters from the end of the name of the directory. */ | |
| 1137 (void) strcpy (pathname_parsed_p, | |
| 1138 pathname_p); | |
| 1139 while (((object_name_p = strrchr (pathname_parsed_p, \ | |
| 1140 '/')) != NULL) && \ | |
| 1141 (dir_nesting_depth <= FFS_DIR_NESTING_DEPTH)) | |
| 1142 { | |
| 1143 | |
| 1144 /* Check for '/..' object names. */ | |
| 1145 if (strcmp (object_name_p, \ | |
| 1146 "/..") == 0x00000000) | |
| 1147 { | |
| 1148 dir_nesting_depth--; | |
| 1149 } | |
| 1150 else | |
| 1151 { | |
| 1152 | |
| 1153 /* Check for '/.' object names. */ | |
| 1154 if (strcmp (object_name_p, \ | |
| 1155 "/.") != 0x00000000) | |
| 1156 { | |
| 1157 dir_nesting_depth++; | |
| 1158 } | |
| 1159 } | |
| 1160 | |
| 1161 /* Truncate the name of the directory in order to search for other '/' */ | |
| 1162 /* characters backwards. */ | |
| 1163 pathname_parsed_p[object_name_p - pathname_parsed_p] = '\x00'; | |
| 1164 } | |
| 1165 | |
| 1166 /* Abort whether the directory nesting depth is exceeded. */ | |
| 1167 if (dir_nesting_depth > FFS_DIR_NESTING_DEPTH) | |
| 1168 { | |
| 1169 return (EFFS_PATHTOODEEP); | |
| 1170 } | |
| 1171 | |
| 1172 /* Create the new directory. */ | |
| 1173 if (CreateDirectory (win32_pathname_p, \ | |
| 1174 NULL) == FALSE) | |
| 1175 { | |
| 1176 | |
| 1177 /* Get the error code. */ | |
| 1178 switch (GetLastError ()) | |
| 1179 { | |
| 1180 | |
| 1181 /* The directory already exists. */ | |
| 1182 case ERROR_ALREADY_EXISTS: | |
| 1183 { | |
| 1184 return (EFFS_EXISTS); | |
| 1185 } | |
| 1186 | |
| 1187 /* Unable to find the specified directory. */ | |
| 1188 case ERROR_PATH_NOT_FOUND: | |
| 1189 { | |
| 1190 return (EFFS_NOTADIR); | |
| 1191 } | |
| 1192 default: | |
| 1193 { | |
| 1194 return (EFFS_DRIVER); | |
| 1195 } | |
| 1196 } | |
| 1197 } | |
| 1198 return (EFFS_OK); | |
| 1199 | |
| 1200 } /************************** End of ffs_mkdir function *************************/ | |
| 1201 | |
| 1202 | |
| 1203 /********************************************************************************/ | |
| 1204 /* */ | |
| 1205 /* Function Name: ffs_opendir */ | |
| 1206 /* */ | |
| 1207 /* Purpose: This function opens a directory and returns the number */ | |
| 1208 /* of objects included into. */ | |
| 1209 /* */ | |
| 1210 /* Input Parameter: */ | |
| 1211 /* pathname_p - Points to the name of the directory to open */ | |
| 1212 /* (0-terminated string). */ | |
| 1213 /* */ | |
| 1214 /* Output Parameter: */ | |
| 1215 /* dir_p - Points to information about the directory (refer */ | |
| 1216 /* to ffs_readdir (···)). */ | |
| 1217 /* */ | |
| 1218 /* Global Parameter: */ | |
| 1219 /* gbl_ffs_ctrl_blk_p - Points to the 'Global Flash File System Control */ | |
| 1220 /* Block'. */ | |
| 1221 /* */ | |
| 1222 /* Note: None. */ | |
| 1223 /* */ | |
| 1224 /* Revision History: */ | |
| 1225 /* 06/29/01 David Lamy-Charrier */ | |
| 1226 /* - Create. */ | |
| 1227 /* */ | |
| 1228 /********************************************************************************/ | |
| 1229 T_FFS_SIZE ffs_opendir (const char *pathname_p, | |
| 1230 T_FFS_DIR *dir_p) | |
| 1231 { | |
| 1232 /* Declare local variables. */ | |
| 1233 char win32_pathname_p[FFS_MAX_PATH_LENGTH] = ""; | |
| 1234 T_FFS_RET return_status = EFFS_OK; | |
| 1235 | |
| 1236 /************************** ffs_opendir function begins *************************/ | |
| 1237 | |
| 1238 /* First, check whether the Flash File System is running. */ | |
| 1239 if ((gbl_ffs_ctrl_blk_p == NULL) || (gbl_ffs_ctrl_blk_p->is_running == FALSE)) | |
| 1240 { | |
| 1241 return (EFFS_AGAIN); | |
| 1242 } | |
| 1243 | |
| 1244 /* Then, convert the name of the directory as defined in the Microsoft® */ | |
| 1245 /* Win32® Programmer's Reference. Abort whether any error occurred. */ | |
| 1246 if (((return_status = ffs_is_valid_object_name (pathname_p)) != EFFS_OK) || \ | |
| 1247 ((return_status = ffs_convert_to_win32_filename (pathname_p, \ | |
| 1248 win32_pathname_p)) != EFFS_OK)) | |
| 1249 { | |
| 1250 return (return_status); | |
| 1251 } | |
| 1252 | |
| 1253 /* Search for a directory whose name matches the specified one. Abort */ | |
| 1254 /* whether the directory does not exist. */ | |
| 1255 if (((dir_p->search_handle = FindFirstFile (strcat (win32_pathname_p, \ | |
| 1256 "//*"), \ | |
| 1257 &(dir_p->find_data))) != INVALID_HANDLE_VALUE) && \ | |
| 1258 ((dir_p->find_data).dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) | |
| 1259 { | |
| 1260 | |
| 1261 /* Declare local block variables. */ | |
| 1262 DWORD object_count = 0x00000000; | |
| 1263 WIN32_FIND_DATA find_data; | |
| 1264 | |
| 1265 /* Go downward through the directory tree. */ | |
| 1266 while (FindNextFile (dir_p->search_handle, \ | |
| 1267 &find_data) == TRUE) | |
| 1268 { | |
| 1269 | |
| 1270 /* Disregard '.' and '..' subdirectories. */ | |
| 1271 if (find_data.cFileName[0] == '.') | |
| 1272 { | |
| 1273 continue; | |
| 1274 } | |
| 1275 object_count++; | |
| 1276 } | |
| 1277 | |
| 1278 /* Close the search handle since no more objects left. */ | |
| 1279 if (object_count > 0x00000000) | |
| 1280 { | |
| 1281 (void) FindClose (dir_p->search_handle); | |
| 1282 | |
| 1283 /* Back to the first object included in the directory. */ | |
| 1284 dir_p->search_handle = FindFirstFile (win32_pathname_p, | |
| 1285 &(dir_p->find_data)); | |
| 1286 } | |
| 1287 return (object_count); | |
| 1288 } | |
| 1289 return (EFFS_NOTFOUND); | |
| 1290 | |
| 1291 } /************************* End of ffs_opendir function ************************/ | |
| 1292 | |
| 1293 | |
| 1294 /********************************************************************************/ | |
| 1295 /* */ | |
| 1296 /* Function Name: ffs_readdir */ | |
| 1297 /* */ | |
| 1298 /* Purpose: This function gets the next entry from a directory. */ | |
| 1299 /* */ | |
| 1300 /* Input Parameters: */ | |
| 1301 /* dir_p - Points to information about the directory (refer */ | |
| 1302 /* to ffs_opendir (···)). */ | |
| 1303 /* buffer_p - Points to the buffer that receives the name of */ | |
| 1304 /* the next entry. */ | |
| 1305 /* size - Specifies the number of bytes of the buffer that */ | |
| 1306 /* receives the name of the next entry. */ | |
| 1307 /* */ | |
| 1308 /* Output Parameter: None. */ | |
| 1309 /* */ | |
| 1310 /* Global Parameter: */ | |
| 1311 /* gbl_ffs_ctrl_blk_p - Points to the 'Global Flash File System Control */ | |
| 1312 /* Block'. */ | |
| 1313 /* */ | |
| 1314 /* Note: This function is not responsible for (de)allocating */ | |
| 1315 /* the buffer that receives the name of the next entry. */ | |
| 1316 /* */ | |
| 1317 /* Revision History: */ | |
| 1318 /* 06/29/01 David Lamy-Charrier */ | |
| 1319 /* - Create. */ | |
| 1320 /* */ | |
| 1321 /********************************************************************************/ | |
| 1322 T_FFS_SIZE ffs_readdir (T_FFS_DIR *dir_p, | |
| 1323 char *buffer_p, | |
| 1324 T_FFS_SIZE size) | |
| 1325 { | |
| 1326 | |
| 1327 /************************** ffs_readdir function begins *************************/ | |
| 1328 | |
| 1329 /* First, check whether the Flash File System is running. */ | |
| 1330 if ((gbl_ffs_ctrl_blk_p == NULL) || (gbl_ffs_ctrl_blk_p->is_running == FALSE)) | |
| 1331 { | |
| 1332 return (EFFS_AGAIN); | |
| 1333 } | |
| 1334 | |
| 1335 /* Go downward through the directory tree. */ | |
| 1336 while (FindNextFile (dir_p->search_handle, \ | |
| 1337 &(dir_p->find_data)) == TRUE) | |
| 1338 { | |
| 1339 | |
| 1340 /* Disregard '.' and '..' subdirectories. */ | |
| 1341 if ((dir_p->find_data).cFileName[0] == '.') | |
| 1342 { | |
| 1343 continue; | |
| 1344 } | |
| 1345 | |
| 1346 /* Copy the name of this entry. */ | |
| 1347 (void) strncpy (buffer_p, \ | |
| 1348 (dir_p->find_data).cFileName, \ | |
| 1349 size); | |
| 1350 return (strlen ((dir_p->find_data).cFileName)); | |
| 1351 } | |
| 1352 | |
| 1353 /* Close the search handle since no more objects left. */ | |
| 1354 if (GetLastError () == ERROR_NO_MORE_FILES) | |
| 1355 { | |
| 1356 (void) FindClose (dir_p->search_handle); | |
| 1357 } | |
| 1358 return (0x00000000); | |
| 1359 | |
| 1360 } /************************* End of ffs_readdir function ************************/ | |
| 1361 | |
| 1362 | |
| 1363 /********************************************************************************/ | |
| 1364 /* */ | |
| 1365 /* Function Name: ffs_rename */ | |
| 1366 /* */ | |
| 1367 /* Purpose: This function renames a file or a directory. */ | |
| 1368 /* */ | |
| 1369 /* Input Parameters: */ | |
| 1370 /* old_pathname_p - Points to the name of the existing file or */ | |
| 1371 /* directory (0-terminated string). */ | |
| 1372 /* new_pathname_p - Points to the new name for the file or the */ | |
| 1373 /* directory (0-terminated string). */ | |
| 1374 /* */ | |
| 1375 /* Output Parameter: None. */ | |
| 1376 /* */ | |
| 1377 /* Global Parameter: */ | |
| 1378 /* gbl_ffs_ctrl_blk_p - Points to the 'Global Flash File System Control */ | |
| 1379 /* Block'. */ | |
| 1380 /* */ | |
| 1381 /* Note: None. */ | |
| 1382 /* */ | |
| 1383 /* Revision History: */ | |
| 1384 /* 02/13/02 Pascal Pompei */ | |
| 1385 /* - Create. */ | |
| 1386 /* */ | |
| 1387 /********************************************************************************/ | |
| 1388 T_FFS_RET ffs_rename (const char *old_pathname_p, | |
| 1389 const char *new_pathname_p) | |
| 1390 { | |
| 1391 /* Declare local variables. */ | |
| 1392 char old_win32_pathname_p[FFS_MAX_PATH_LENGTH] = ""; | |
| 1393 char new_win32_pathname_p[FFS_MAX_PATH_LENGTH] = ""; | |
| 1394 T_FFS_RET return_status = EFFS_OK; | |
| 1395 | |
| 1396 /************************** ffs_rename function begins **************************/ | |
| 1397 | |
| 1398 /* First, check whether the Flash File System is running. */ | |
| 1399 if ((gbl_ffs_ctrl_blk_p == NULL) || (gbl_ffs_ctrl_blk_p->is_running == FALSE)) | |
| 1400 { | |
| 1401 return (EFFS_AGAIN); | |
| 1402 } | |
| 1403 | |
| 1404 /* Then, convert both pathnames as defined in the Microsoft® Win32® */ | |
| 1405 /* Programmer's Reference. Abort whether any error occurred. */ | |
| 1406 if (((return_status = ffs_is_valid_object_name (old_pathname_p)) != EFFS_OK) || \ | |
| 1407 ((return_status = ffs_is_valid_object_name (new_pathname_p)) != EFFS_OK) || \ | |
| 1408 ((return_status = ffs_convert_to_win32_filename (old_pathname_p, \ | |
| 1409 old_win32_pathname_p)) != EFFS_OK) || \ | |
| 1410 ((return_status = ffs_convert_to_win32_filename (new_pathname_p, \ | |
| 1411 new_win32_pathname_p)) != EFFS_OK)) | |
| 1412 { | |
| 1413 return (return_status); | |
| 1414 } | |
| 1415 | |
| 1416 /* Rename the file or the directory. */ | |
| 1417 if (MoveFile (old_win32_pathname_p, \ | |
| 1418 new_win32_pathname_p) == FALSE) | |
| 1419 { | |
| 1420 | |
| 1421 /* Get the error code. */ | |
| 1422 switch (GetLastError ()) | |
| 1423 { | |
| 1424 | |
| 1425 /* File or directory already exists. */ | |
| 1426 case ERROR_ALREADY_EXISTS: | |
| 1427 | |
| 1428 /* The file exists. */ | |
| 1429 case ERROR_FILE_EXISTS: | |
| 1430 { | |
| 1431 return (EFFS_EXISTS); | |
| 1432 } | |
| 1433 | |
| 1434 /* Access denied. */ | |
| 1435 case ERROR_ACCESS_DENIED: | |
| 1436 | |
| 1437 /* Unable to access the file because it is being used by another */ | |
| 1438 /* process. */ | |
| 1439 case ERROR_SHARING_VIOLATION: | |
| 1440 { | |
| 1441 return (EFFS_LOCKED); | |
| 1442 } | |
| 1443 default: | |
| 1444 { | |
| 1445 return (EFFS_NOTFOUND); | |
| 1446 } | |
| 1447 } | |
| 1448 } | |
| 1449 return (EFFS_OK); | |
| 1450 | |
| 1451 } /************************* End of ffs_rename function *************************/ | |
| 1452 | |
| 1453 | |
| 1454 /* SAMIR | |
| 1455 Function taken from ffs_env.c | |
| 1456 */ | |
| 1457 T_FFS_SIZE ffs_init (void) | |
| 1458 { | |
| 1459 | |
| 1460 /*************************** ffs_init function begins ***************************/ | |
| 1461 | |
| 1462 gbl_ffs_ctrl_blk_p = &gbl_ffs_ctrl_blk; | |
| 1463 | |
| 1464 /* Initialize the current working directory. */ | |
| 1465 if (ffs_init_working_folder () != EFFS_OK) | |
| 1466 { | |
| 1467 return (EFFS_AGAIN); | |
| 1468 } | |
| 1469 | |
| 1470 /* State the Flash File System as running. */ | |
| 1471 gbl_ffs_ctrl_blk_p->is_running = TRUE; | |
| 1472 | |
| 1473 return (EFFS_OK); | |
| 1474 | |
| 1475 } |
