Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

363 lines
9.0 KiB

  1. /*++
  2. Copyright (c) 1988-1999 Microsoft Corporation
  3. Module Name:
  4. ffirst.c
  5. Abstract:
  6. Wrappers for file enumeration
  7. --*/
  8. #include "cmd.h"
  9. PHANDLE FFhandles = NULL;
  10. unsigned FFhndlsaved = 0;
  11. extern unsigned DosErr ;
  12. BOOLEAN FindFirstNt( PTCHAR, PWIN32_FIND_DATA, PHANDLE );
  13. BOOLEAN FindNextNt ( PWIN32_FIND_DATA, HANDLE );
  14. BOOLEAN FindFirst(
  15. BOOL(* fctAttribMatch) (PWIN32_FIND_DATA pffBuf, ULONG attr),
  16. PTCHAR fspec,
  17. ULONG attr,
  18. PWIN32_FIND_DATA pffBuf,
  19. PHANDLE phandle );
  20. BOOLEAN FindNext (
  21. BOOL(* fctAttribMatch) (PWIN32_FIND_DATA pffBuf, ULONG attr),
  22. PWIN32_FIND_DATA pffBuf,
  23. ULONG attr,
  24. HANDLE handle
  25. );
  26. BOOL IsDosAttribMatch( PWIN32_FIND_DATA, ULONG );
  27. BOOL IsNtAttribMatch( PWIN32_FIND_DATA, ULONG );
  28. int findclose( HANDLE );
  29. //
  30. // Under OS/2, we always return entries that are normal, archived or
  31. // read-only (god knows why).
  32. //
  33. // SRCHATTR contains those attribute bits that are used for matching.
  34. //
  35. #define SRCHATTR (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_DIRECTORY)
  36. /*** IsDosAttribMatch - Simulates the attribute matching from OS/2
  37. *
  38. * Purpose:
  39. * This function determines if the passed in find file buffer has a
  40. * match under the OS/2 find file rules.
  41. *
  42. * Args:
  43. * ffbuf: Buffer returned from FileFirst or Findnext
  44. * attr: Attributes to qualify search
  45. *
  46. * Returns:
  47. * TRUE: if buffer has a attribute match
  48. * FALSE: if not
  49. */
  50. BOOL
  51. IsDosAttribMatch(
  52. IN PWIN32_FIND_DATA pffBuf,
  53. IN ULONG attr
  54. ) {
  55. //
  56. // We emulate the OS/2 behaviour of attribute matching. The semantics
  57. // are evil, so I provide no explanation.
  58. //
  59. pffBuf->dwFileAttributes &= (0x000000FF & ~(FILE_ATTRIBUTE_NORMAL));
  60. if (! ((pffBuf->dwFileAttributes & SRCHATTR) & ~(attr))) {
  61. return TRUE;
  62. } else {
  63. return FALSE;
  64. }
  65. }
  66. BOOL
  67. IsNtAttribMatch(
  68. PWIN32_FIND_DATA pffBuf,
  69. ULONG attr
  70. ) {
  71. UNREFERENCED_PARAMETER( pffBuf );
  72. UNREFERENCED_PARAMETER( attr );
  73. //
  74. // for nt calls always return entry. selection should
  75. // should be based upon callers needs. This is primarily used
  76. // in DIR.
  77. return( TRUE );
  78. }
  79. /*** f_how_many - find how many files are there per fspec with given attr
  80. *
  81. * Args:
  82. * fspec: String pointer to file specification.
  83. * attr: Attributes to qualify search
  84. *
  85. * Returns:
  86. * number of files found or -1 if a file is a directory.
  87. */
  88. int
  89. f_how_many(
  90. PTCHAR fspec,
  91. ULONG attr
  92. ) {
  93. WIN32_FIND_DATA ffBuf;
  94. PWIN32_FIND_DATA pffBuf;
  95. PHANDLE phandle;
  96. HANDLE hnFirst ;
  97. unsigned rc;
  98. int cnt=0;
  99. pffBuf = &ffBuf;
  100. if ( ! ffirst (fspec, attr, pffBuf, &hnFirst )) {
  101. if ( ! ffirst (fspec, FILE_ATTRIBUTE_DIRECTORY, pffBuf, &hnFirst )) {
  102. return (0);
  103. }
  104. else {
  105. findclose(hnFirst);
  106. return (f_RET_DIR);
  107. }
  108. }
  109. do {
  110. cnt++;
  111. } while ( fnext (pffBuf, attr, hnFirst ));
  112. findclose(hnFirst) ;
  113. return (cnt);
  114. }
  115. /*** ffirst - find first file/directory and set up find handles
  116. *
  117. * Purpose:
  118. * This function opens a find first handle. I also returns the first
  119. * qualified file/directory. It simulates the DosFindFirst behavior.
  120. *
  121. * Args:
  122. * fspec: String pointer to file specification.
  123. * attr: Attributes to qualify search
  124. * ffbuf: Buffer to hold inforation on found file/directory
  125. * handle: Find first handle
  126. *
  127. * Returns:
  128. * TRUE: If match found
  129. * FALSE: if not
  130. * DosErr: Contains return code if FALSE function return
  131. */
  132. BOOLEAN
  133. FindFirst(
  134. IN BOOL(* fctAttribMatch) (PWIN32_FIND_DATA pffBuf, ULONG attr),
  135. IN PTCHAR fspec,
  136. IN ULONG attr,
  137. IN PWIN32_FIND_DATA pffBuf,
  138. OUT PHANDLE phandle
  139. ) {
  140. BOOLEAN rcode = FALSE;
  141. //
  142. // Loop through looking for a file that matching attributes
  143. //
  144. *phandle = FindFirstFile(fspec, pffBuf);
  145. while (*phandle != (HANDLE) -1) {
  146. if (fctAttribMatch(pffBuf, attr)) {
  147. DosErr = 0;
  148. rcode = TRUE;
  149. break;
  150. }
  151. if (!FindNextFile( *phandle, pffBuf )) {
  152. FindClose( *phandle );
  153. *phandle = INVALID_HANDLE_VALUE;
  154. break;
  155. }
  156. }
  157. //
  158. // If we did find a file (have a handle to prove it) then
  159. // setup a table of saved open find first handles. If we have
  160. // to clean up then these handle can all be closed.
  161. //
  162. if (*phandle != INVALID_HANDLE_VALUE) {
  163. //
  164. // Check if we already created the table. If we have not
  165. // then allocate space for table.
  166. //
  167. if (FFhandles == NULL) {
  168. FFhandles = (PHANDLE)HeapAlloc(GetProcessHeap(), 0, 5 * sizeof(PHANDLE));
  169. } else {
  170. //
  171. // Check if we have space to hold new handle entry
  172. //
  173. if (((FFhndlsaved + 1)* sizeof(PHANDLE)) > HeapSize(GetProcessHeap(), 0, FFhandles)) {
  174. PVOID Temp = HeapReAlloc(GetProcessHeap(), 0, (void*)FFhandles, (FFhndlsaved+1)*sizeof(PHANDLE));
  175. if (Temp == NULL) {
  176. DosErr = GetLastError( );
  177. FindClose( *phandle );
  178. *phandle = INVALID_HANDLE_VALUE;
  179. return FALSE;
  180. }
  181. FFhandles = Temp;
  182. }
  183. }
  184. if (FFhandles != NULL) {
  185. FFhandles[FFhndlsaved++] = *phandle;
  186. }
  187. rcode = TRUE;
  188. }
  189. if (!rcode) {
  190. DosErr = GetLastError();
  191. }
  192. return(rcode);
  193. }
  194. BOOLEAN
  195. FindFirstNt(
  196. IN PTCHAR fspec,
  197. IN PWIN32_FIND_DATA pffBuf,
  198. OUT PHANDLE phandle
  199. )
  200. {
  201. return(FindFirst(IsNtAttribMatch, fspec, 0, pffBuf, phandle));
  202. }
  203. BOOLEAN
  204. ffirst(
  205. PTCHAR fspec,
  206. ULONG attr,
  207. PWIN32_FIND_DATA pffBuf,
  208. PHANDLE phandle
  209. )
  210. {
  211. return(FindFirst(IsDosAttribMatch, fspec, attr, pffBuf, phandle));
  212. }
  213. /*** fnext - find next file/directory
  214. *
  215. * Purpose:
  216. * This function search for the next qualified file or directory.
  217. * ffirst should have been called first and the returned file handle
  218. * should be passed into fnext.
  219. * Args:
  220. * handle: Find first handle
  221. * attr: Attributes to qualify search
  222. * ffbuf: Buffer to hold information on found file/directory
  223. *
  224. * Returns:
  225. * TRUE: If match found
  226. * FALSE: if not
  227. * DosErr: Contains return code if FALSE function return
  228. */
  229. BOOLEAN
  230. FindNextNt (
  231. IN PWIN32_FIND_DATA pffBuf,
  232. IN HANDLE handle
  233. ) {
  234. //
  235. // attributes are ignored for this kind of call
  236. //
  237. return( FindNext( IsNtAttribMatch, pffBuf, 0, handle) );
  238. }
  239. BOOLEAN
  240. fnext (
  241. IN PWIN32_FIND_DATA pffBuf,
  242. IN ULONG attr,
  243. IN HANDLE handle
  244. ) {
  245. return( FindNext( IsDosAttribMatch, pffBuf, attr, handle) );
  246. }
  247. BOOLEAN
  248. FindNext (
  249. IN BOOL(* fctAttribMatch) (PWIN32_FIND_DATA pffBuf, ULONG attr),
  250. IN PWIN32_FIND_DATA pffBuf,
  251. IN ULONG attr,
  252. IN HANDLE handle
  253. ) {
  254. //
  255. // Loop through looking for a file that matching attributes
  256. //
  257. while (FindNextFile( handle, pffBuf )) {
  258. if (fctAttribMatch( pffBuf, attr )) {
  259. DosErr = 0;
  260. return(TRUE);
  261. }
  262. }
  263. DosErr = GetLastError();
  264. return(FALSE);
  265. }
  266. int findclose(hn)
  267. HANDLE hn;
  268. {
  269. unsigned cnt;
  270. unsigned cnt2;
  271. DEBUG((CTGRP, COLVL, "findclose: handle %lx",hn)) ;
  272. // Locate handle in table
  273. //
  274. for (cnt = 0; (cnt < FFhndlsaved) && FFhandles[cnt] != hn ; cnt++ ) {
  275. ;
  276. }
  277. //
  278. // Remove handle from table
  279. //
  280. DEBUG((CTGRP, COLVL, "\t found handle in table at %d",cnt)) ;
  281. if (cnt < FFhndlsaved) {
  282. for (cnt2 = cnt; cnt2 < (FFhndlsaved - 1) ; cnt2++) {
  283. FFhandles[cnt2] = FFhandles[cnt2 + 1];
  284. }
  285. FFhndlsaved--;
  286. }
  287. //
  288. // Close even if we couldn't find it in table
  289. //
  290. DEBUG((CTGRP, COLVL, "\t closing handle %lx ",hn)) ;
  291. if (FindClose(hn)) /* Close even if we couldn't find it in table */
  292. return(0);
  293. else
  294. DEBUG((CTGRP, COLVL, "\t Error closing handle %lx ",hn)) ;
  295. return(GetLastError());
  296. }