home *** CD-ROM | disk | FTP | other *** search
/ Power GUI Programming with VisualAge C++ / powergui.iso / trialva / ibmcppw / sdk / mapi / win16 / dev / common / findnext.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-07-11  |  8.9 KB  |  355 lines

  1. /*
  2.  *  FINDNEXT.C
  3.  *  
  4.  *  File I/O functions that also drag in time conversion code.
  5.  *
  6.  *  Copyright 1993-1995 Microsoft Corporation. All Rights Reserved.
  7.  */
  8.  
  9. #pragma warning(disable:4001)   /* single line comments */
  10. #pragma warning(disable:4054)   /* cast function pointer to data pointer */
  11. #pragma warning(disable:4100)   /* unreferenced formal parameter */
  12. #pragma warning(disable:4127)   /* conditional expression is constant */
  13. #pragma warning(disable:4201)   /* nameless struct/union */
  14. #pragma warning(disable:4204)   /* non-constant aggregate initializer */
  15. #pragma warning(disable:4209)   /* benign typedef redefinition */
  16. #pragma warning(disable:4214)   /* bit field types other than int */
  17. #pragma warning(disable:4505)   /* unreferenced local function removed */
  18. #pragma warning(disable:4514)   /* unreferenced inline function removed */
  19. #pragma warning(disable:4702)   /* unreachable code */
  20. #pragma warning(disable:4704)   /* inline assembler turns off global optimizer */
  21. #pragma warning(disable:4705)   /* statement has no effect */
  22. #pragma warning(disable:4706)   /* assignment within conditional expression */
  23. #pragma warning(disable:4710)   /* function not expanded */
  24. #pragma warning(disable:4115)   /* named type def in parens */
  25.  
  26. #include <windows.h>
  27. #pragma warning(disable:4001)   /* single line comments */
  28. #include <windowsx.h>
  29. #include <mapiwin.h>
  30. #include <mapidbg.h>
  31. #include <compobj.h>
  32. #include <mapicode.h>
  33. #include <mapiperf.h>
  34. #include <_mapiwin.h>
  35.  
  36. #include <memory.h>     /* for memcpy, memset */
  37.  
  38. #pragma SEGMENT(Common)
  39.  
  40. /* cribbed from DOS.H */
  41.  
  42. struct MyDOS_find_t {
  43.     char reserved[21];
  44.     char attrib;
  45.     unsigned wr_time;
  46.     unsigned wr_date;
  47.     long size;
  48.     char name[13];
  49.     };
  50.  
  51. #pragma warning(disable: 4704)      /* asm disables global optimizations */
  52.  
  53. LPVOID  PvGetDTA(void);
  54. void    SetDTA(LPVOID pv);
  55.  
  56. #ifdef WIN16
  57.  
  58. static FILETIME ftZero = { 0, 0 };
  59.  
  60. /*
  61.  *  FindFirstFile
  62.  *  
  63.  *  Limitations
  64.  *      dwReserved0, dwReserved1 and cAlternateFileName are
  65.  *      not supported in the WIN32_FIND_DATA structure.
  66.  */
  67.  
  68. #pragma warning(disable: 4769)
  69.  
  70. HANDLE __export WINAPI
  71. FindFirstFile(LPCSTR lpFileName, LPWIN32_FIND_DATA lpFindFileData)
  72. {
  73.     FILETIME    ft;
  74.     WORD        segPath;
  75.     WORD        offPath;
  76.     WORD        segDTA;
  77.     WORD        offDTA;
  78.     LPVOID      pvDTASave = NULL;
  79.     char        szFile[MAX_PATH];
  80.  
  81.     HANDLE      hfind = NULL;
  82.     struct MyDOS_find_t FAR *pfind = NULL;
  83.  
  84.  
  85.     Assert(!IsBadStringPtr(lpFileName, MAX_PATH));
  86.     Assert(!IsBadWritePtr(lpFindFileData, sizeof(WIN32_FIND_DATA)));
  87.  
  88.     AnsiToOem(lpFileName, szFile);
  89.     memset(lpFindFileData, -1, sizeof(WIN32_FIND_DATA));
  90.  
  91.     if (!(hfind = GlobalAlloc(GMEM_FIXED, sizeof(struct MyDOS_find_t))) ||
  92.         !(pfind = (struct MyDOS_find_t FAR *)GlobalLock(hfind)))
  93.     {
  94.         DebugTrace("FindFirstFile: no memory for DOS finddata\n");
  95.         return INVALID_HANDLE_VALUE;
  96.     }
  97.  
  98.     segPath = SELECTOROF(szFile);
  99.     offPath = OFFSETOF(szFile);
  100.     segDTA = SELECTOROF(pfind);
  101.     offDTA = OFFSETOF(pfind);
  102.  
  103.     pvDTASave = PvGetDTA();
  104.     Assert(pvDTASave);
  105.     SetDTA(pfind);
  106.  
  107.     _asm
  108.     {
  109.         push ds
  110.         mov cx, 10h                 ; include subdirectories
  111.         mov dx, segPath             ; file name
  112.         mov ds, dx
  113.         mov dx, offPath
  114.         mov ah, 4eh                 ; Find First File
  115.         call DOS3Call
  116.         pop ds
  117.  
  118.         jnc fff10
  119.         jmp fail
  120.  
  121. fff10:
  122.             ; else fall through
  123.  
  124.     }
  125.  
  126.     lpFindFileData->dwFileAttributes = pfind->attrib;
  127.     OemToAnsi(pfind->name, lpFindFileData->cFileName);
  128.  
  129.     if (!DosDateTimeToFileTime ((WORD)pfind->wr_date, (WORD)pfind->wr_time, &ft)
  130.      || !LocalFileTimeToFileTime (&ft, &lpFindFileData->ftLastAccessTime))
  131.     {
  132.         //  Time was bogus. This can happen, for instance, on Netware.
  133.         //  Return zeroes but do not fail.
  134.         lpFindFileData->ftLastAccessTime = ftZero;
  135.         lpFindFileData->ftCreationTime = ftZero;
  136.         lpFindFileData->ftLastWriteTime = ftZero;
  137.     }
  138.     else
  139.     {
  140.         lpFindFileData->ftCreationTime = lpFindFileData->ftLastAccessTime;
  141.         lpFindFileData->ftLastWriteTime = lpFindFileData->ftLastAccessTime;
  142.     }
  143.  
  144.     lpFindFileData->nFileSizeHigh = 0;
  145.     lpFindFileData->nFileSizeLow = pfind->size;
  146.  
  147.     SetDTA(pvDTASave);
  148.     GlobalUnlock(hfind);
  149.  
  150.     return hfind;
  151.  
  152. fail:
  153.     SetDTA(pvDTASave);
  154.     if (hfind)
  155.     {
  156.         if (pfind)
  157.             GlobalUnlock(hfind);
  158.         GlobalFree(hfind);
  159.     }
  160.  
  161. #ifdef  DEBUG
  162.     if (GetLastError() != ERROR_NO_MORE_FILES)
  163.         DebugTraceDos(FindFirstFile);
  164. #endif  
  165.     return INVALID_HANDLE_VALUE;
  166. }
  167.  
  168. /*
  169.  *  FindNextFile
  170.  *  
  171.  *  Limitations
  172.  *      dwReserved0, dwReserved1 and cAlternateFileName are
  173.  *      not supported in the WIN32_FIND_DATA structure.
  174.  */
  175. BOOL __export WINAPI
  176. FindNextFile(HANDLE hFindFile, LPWIN32_FIND_DATA lpFindFileData)
  177. {
  178.     FILETIME    ft;
  179.     LPVOID      pvDTASave = NULL;
  180.     struct MyDOS_find_t FAR *pfind = NULL;
  181.     BOOL        f = FALSE;
  182.  
  183.     if (!GlobalSize(hFindFile) ||
  184.         !(pfind = (struct MyDOS_find_t FAR *)GlobalLock(hFindFile)))
  185.     {
  186.         DebugTraceArg(FindNextFile, "Invalid find handle");
  187.         return FALSE;
  188.     }
  189.  
  190.     Assert(!IsBadWritePtr(lpFindFileData, sizeof(WIN32_FIND_DATA)));
  191.  
  192.     memset(lpFindFileData, -1, sizeof(WIN32_FIND_DATA));
  193.  
  194.     pvDTASave = PvGetDTA();
  195.     Assert(pvDTASave);
  196.     SetDTA(pfind);
  197.  
  198.     _asm
  199.     {
  200.         mov ah, 4fh                 ; Find Next File
  201.         call DOS3Call
  202.         jc fnfErr10
  203.  
  204.         mov f, TRUE                 ; signal success
  205.  
  206. fnfErr10:
  207.     }
  208.  
  209.     if (!f)
  210.     {
  211. #ifdef  DEBUG
  212.         if (GetLastError() != ERROR_NO_MORE_FILES)
  213.             DebugTraceDos(FindNextFile);
  214. #endif  
  215.         goto fail;
  216.     }
  217.  
  218.     lpFindFileData->dwFileAttributes = pfind->attrib;
  219.     OemToAnsi(pfind->name, lpFindFileData->cFileName);
  220.  
  221.     if (!DosDateTimeToFileTime ((WORD)pfind->wr_date, (WORD)pfind->wr_time, &ft)
  222.      || !LocalFileTimeToFileTime (&ft, &lpFindFileData->ftLastAccessTime))
  223.     {
  224.         //  Time was bogus. This can happen, for instance, on Netware.
  225.         //  Return zeroes but do not fail.
  226.         lpFindFileData->ftLastAccessTime = ftZero;
  227.         lpFindFileData->ftCreationTime = ftZero;
  228.         lpFindFileData->ftLastWriteTime = ftZero;
  229.     }
  230.     else
  231.     {
  232.         lpFindFileData->ftCreationTime = lpFindFileData->ftLastAccessTime;
  233.         lpFindFileData->ftLastWriteTime = lpFindFileData->ftLastAccessTime;
  234.     }
  235.  
  236.     lpFindFileData->nFileSizeHigh = 0;
  237.     lpFindFileData->nFileSizeLow = pfind->size;
  238.  
  239.     SetDTA(pvDTASave);
  240.     GlobalUnlock(hFindFile);
  241.  
  242.     return TRUE;
  243.  
  244. fail:
  245.     SetDTA(pvDTASave);
  246.     if (pfind)
  247.         GlobalUnlock(hFindFile);
  248.     return FALSE;
  249. }
  250.  
  251. /*
  252.  *  FindClose
  253.  */
  254. BOOL __export WINAPI
  255. FindClose(HANDLE hFindFile)
  256. {
  257.     BOOL    f;
  258.  
  259.     if (hFindFile == INVALID_HANDLE_VALUE)
  260.         return 0;
  261.  
  262.     f = (GlobalSize(hFindFile) != 0L);
  263.     GlobalFree(hFindFile);
  264.     return f;
  265. }
  266.  
  267. #pragma warning(default: 4769)
  268.  
  269.  
  270. /*
  271.  *  GetFileTime
  272.  *  
  273.  *  Limitations
  274.  *      Only last-modified time is supported; no create or access
  275.  *      time. Fails if either of the latter is requested.
  276.  */
  277. BOOL __export WINAPI
  278. GetFileTime(HANDLE hFile, FILETIME FAR *lpftCreation, FILETIME FAR *lpftLastAccess,
  279.     FILETIME FAR *lpftLastWrite)
  280. {
  281.     FILETIME    ftLocal;
  282.     WORD        wDate;
  283.     WORD        wTime;
  284.  
  285.     Assert(!IsBadWritePtr(lpftLastWrite, sizeof(FILETIME)));
  286.  
  287.     if (lpftCreation || lpftLastAccess)
  288.     {
  289.         DebugTraceArg(GetFileTime, "lpftCreation and lpftLastAccess are unsupported");
  290.         return FALSE;
  291.     }
  292.  
  293.     _asm {
  294.         mov bx, hFile
  295.         mov ax, 5700h               ; Get File Date and Time
  296.         call DOS3Call
  297.         jc gftErr
  298.  
  299.         mov wDate, dx
  300.         mov wTime, cx
  301.     }
  302.  
  303.     if (!DosDateTimeToFileTime(wDate, wTime, &ftLocal))
  304.         goto gftErr;
  305.     return LocalFileTimeToFileTime (&ftLocal, lpftLastWrite);
  306.  
  307. gftErr:
  308.     DebugTraceDos(GetFileTime);
  309.     return FALSE;
  310. }
  311.  
  312. #pragma warning(disable: 4035)      /* no return value */
  313.  
  314. LPVOID
  315. PvGetDTA()
  316. {
  317.     _asm
  318.     {
  319.         mov ah, 2fh                 ; Get Disk Transfer Address
  320.         call DOS3Call
  321.                                     ; no failure report
  322.         mov dx, es                  ; return as long
  323.         mov ax, bx
  324.     }
  325. }
  326.  
  327. #pragma warning(default: 4035)      /* no return value */
  328.  
  329. void
  330. SetDTA(LPVOID pvDTA)
  331. {
  332.     WORD    segDTA;
  333.     WORD    offDTA;
  334.  
  335.     Assert(pvDTA);
  336.  
  337.     segDTA = SELECTOROF(pvDTA);
  338.     offDTA = OFFSETOF(pvDTA);
  339.  
  340.     _asm {
  341.         push ds
  342.         mov dx, segDTA
  343.         mov ds, dx
  344.         mov dx, offDTA
  345.         mov ah, 1ah                 ; Set Disk Transfer Address
  346.         call DOS3Call
  347.                                     ; no failure report
  348.         pop ds
  349.     }
  350. }
  351.  
  352.  
  353.  
  354. #endif  /* WIN16 */
  355.