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 }