Source code of Windows XP (NT5)
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.

388 lines
9.4 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. fileio.c
  5. Abstract:
  6. This source implements a stdio-like facility.
  7. Author:
  8. Jim Stewart June 1993
  9. Revision History:
  10. --*/
  11. #include "precomp.h"
  12. #include "hosts.h"
  13. #include <string.h>
  14. //
  15. // Private Definitions
  16. //
  17. //
  18. // Local Variables
  19. //
  20. //
  21. // Local (Private) Functions
  22. //
  23. PUCHAR
  24. LmpMapFile (
  25. IN HANDLE handle,
  26. IN OUT int *pnbytes
  27. );
  28. //******************* Pageable Routine Declarations ****************
  29. #ifdef ALLOC_PRAGMA
  30. #pragma CTEMakePageable(PAGE, LmCloseFile)
  31. #pragma CTEMakePageable(PAGE, LmFgets)
  32. #pragma CTEMakePageable(PAGE, LmpMapFile)
  33. #pragma CTEMakePageable(PAGE, LmOpenFile)
  34. #endif
  35. //******************* Pageable Routine Declarations ****************
  36. //----------------------------------------------------------------------------
  37. NTSTATUS
  38. LmCloseFile (
  39. IN PLM_FILE pfile
  40. )
  41. /*++
  42. Routine Description:
  43. This function closes a file opened via LmOpenFile(), and frees its
  44. LM_FILE object.
  45. Arguments:
  46. pfile - pointer to the LM_FILE object
  47. Return Value:
  48. An NTSTATUS value.
  49. --*/
  50. {
  51. NTSTATUS status;
  52. CTEPagedCode();
  53. CTEMemFree(pfile->f_buffer);
  54. status = ZwClose(pfile->f_handle);
  55. ASSERT(status == STATUS_SUCCESS);
  56. CTEMemFree(pfile);
  57. return(status);
  58. } // LmCloseFile
  59. //----------------------------------------------------------------------------
  60. PUCHAR
  61. LmFgets (
  62. IN PLM_FILE pfile,
  63. OUT int *nbytes
  64. )
  65. /*++
  66. Routine Description:
  67. This function is vaguely similar to fgets(3).
  68. Starting at the current seek position, it reads through a newline
  69. character, or the end of the file. If a newline is encountered, it
  70. is replaced with a NULL character.
  71. Arguments:
  72. pfile - file to read from
  73. nbytes - the number of characters read, excluding the NULL character
  74. Return Value:
  75. A pointer to the beginning of the line, or NULL if we are at or past
  76. the end of the file.
  77. --*/
  78. {
  79. PUCHAR endOfLine;
  80. PUCHAR startOfLine;
  81. size_t maxBytes;
  82. CTEPagedCode();
  83. startOfLine = pfile->f_current;
  84. if (startOfLine >= pfile->f_limit)
  85. {
  86. return((PUCHAR) NULL);
  87. }
  88. maxBytes = (size_t)(pfile->f_limit - pfile->f_current);
  89. endOfLine = (PUCHAR) memchr(startOfLine, (UCHAR) '\n', maxBytes);
  90. if (!endOfLine)
  91. {
  92. IF_DBG(NBT_DEBUG_LMHOST)
  93. KdPrint(("NBT: lmhosts file doesn't end in '\\n'"));
  94. endOfLine = pfile->f_limit;
  95. }
  96. *endOfLine = (UCHAR) NULL;
  97. pfile->f_current = endOfLine + 1;
  98. (pfile->f_lineno)++;
  99. ASSERT(pfile->f_current <= pfile->f_limit+1);
  100. *nbytes = (int)(endOfLine - startOfLine);
  101. return(startOfLine);
  102. } // LmFgets
  103. //----------------------------------------------------------------------------
  104. PUCHAR
  105. LmpMapFile (
  106. IN HANDLE handle,
  107. IN OUT int *pnbytes
  108. )
  109. /*++
  110. Routine Description:
  111. This function reads an entire file into memory.
  112. Arguments:
  113. handle - file handle
  114. pnbytes - size of the whole file
  115. Return Value:
  116. the buffer allocated, or NULL if unsuccessful.
  117. --*/
  118. {
  119. PUCHAR buffer;
  120. NTSTATUS status;
  121. IO_STATUS_BLOCK iostatus;
  122. FILE_STANDARD_INFORMATION stdInfo;
  123. LARGE_INTEGER offset ={0, 0};
  124. LARGE_INTEGER length ={0x7fffffff, 0x7fffffff};
  125. CTEPagedCode();
  126. status = ZwQueryInformationFile(
  127. handle, // FileHandle
  128. &iostatus, // IoStatusBlock
  129. (PVOID) &stdInfo, // FileInformation
  130. sizeof(stdInfo), // Length
  131. FileStandardInformation); // FileInformationClass
  132. if (status != STATUS_SUCCESS)
  133. {
  134. IF_DBG(NBT_DEBUG_LMHOST)
  135. KdPrint(("NBT: ZwQueryInformationFile(std) = %X\n", status));
  136. return(NULL);
  137. }
  138. length = stdInfo.EndOfFile; // structure copy
  139. if (length.HighPart)
  140. {
  141. return(NULL);
  142. }
  143. buffer = NbtAllocMem (length.LowPart+2, NBT_TAG2('18'));
  144. if (buffer != NULL)
  145. {
  146. status = ZwReadFile(
  147. handle, // FileHandle
  148. NULL, // Event
  149. NULL, // ApcRoutine
  150. NULL, // ApcContext
  151. &iostatus, // IoStatusBlock
  152. buffer, // Buffer
  153. length.LowPart, // Length
  154. &offset, // ByteOffset
  155. NULL); // Key
  156. if (status != STATUS_SUCCESS)
  157. {
  158. IF_DBG(NBT_DEBUG_LMHOST)
  159. KdPrint(("NBT: ZwReadFile(std) = %X\n", status));
  160. }
  161. ASSERT(status != STATUS_PENDING);
  162. if (iostatus.Status != STATUS_SUCCESS || status != STATUS_SUCCESS)
  163. {
  164. CTEMemFree(buffer);
  165. return(NULL);
  166. }
  167. *pnbytes = length.LowPart;
  168. }
  169. return(buffer);
  170. } // LmpMapFile
  171. //----------------------------------------------------------------------------
  172. PLM_FILE
  173. LmOpenFile (
  174. IN PUCHAR path
  175. )
  176. /*++
  177. Routine Description:
  178. This function opens a file for use by LmFgets().
  179. Arguments:
  180. path - a fully specified, complete path to the file.
  181. Return Value:
  182. A pointer to an LM_FILE object, or NULL if unsuccessful.
  183. --*/
  184. {
  185. NTSTATUS status;
  186. HANDLE handle;
  187. PLM_FILE pfile;
  188. IO_STATUS_BLOCK iostatus;
  189. OBJECT_ATTRIBUTES attributes;
  190. UNICODE_STRING ucPath;
  191. PUCHAR start;
  192. int nbytes;
  193. OEM_STRING String;
  194. PUCHAR LongerPath;
  195. CTEPagedCode();
  196. ASSERT(KeGetCurrentIrql() <= APC_LEVEL);
  197. status = LmGetFullPath(path,&LongerPath);
  198. if (NT_SUCCESS(status))
  199. {
  200. RtlInitString(&String,LongerPath);
  201. status = RtlAnsiStringToUnicodeString(&ucPath,&String,TRUE);
  202. if (NT_SUCCESS(status))
  203. {
  204. #ifdef HDL_FIX
  205. InitializeObjectAttributes (&attributes, // POBJECT_ATTRIBUTES
  206. &ucPath, // ObjectName
  207. OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, // Attributes
  208. (HANDLE) NULL, // RootDirectory
  209. (PSECURITY_DESCRIPTOR) NULL); // SecurityDescriptor
  210. #else
  211. InitializeObjectAttributes (&attributes, // POBJECT_ATTRIBUTES
  212. &ucPath, // ObjectName
  213. OBJ_CASE_INSENSITIVE, // Attributes
  214. (HANDLE) NULL, // RootDirectory
  215. (PSECURITY_DESCRIPTOR) NULL); // SecurityDescriptor
  216. #endif // HDL_FIX
  217. status = ZwCreateFile (&handle, // FileHandle
  218. SYNCHRONIZE | FILE_READ_DATA, // DesiredAccess
  219. &attributes, // ObjectAttributes
  220. &iostatus, // IoStatusBlock
  221. 0, // AllocationSize
  222. FILE_ATTRIBUTE_NORMAL, // FileAttributes
  223. FILE_SHARE_READ | FILE_SHARE_WRITE, // ShareAccess
  224. FILE_OPEN, // CreateDisposition
  225. FILE_SYNCHRONOUS_IO_NONALERT, // OpenOptions
  226. NULL, // EaBuffer
  227. 0); // EaLength
  228. if (NT_SUCCESS(status))
  229. {
  230. start = LmpMapFile(handle, &nbytes);
  231. if (start)
  232. {
  233. pfile = (PLM_FILE) NbtAllocMem (sizeof(LM_FILE), NBT_TAG2('19'));
  234. if (pfile)
  235. {
  236. KeInitializeSpinLock(&(pfile->f_lock));
  237. pfile->f_refcount = 1;
  238. pfile->f_handle = handle;
  239. pfile->f_lineno = 0;
  240. pfile->f_fileOffset.HighPart = 0;
  241. pfile->f_fileOffset.LowPart = 0;
  242. pfile->f_current = start;
  243. pfile->f_buffer = start;
  244. pfile->f_limit = pfile->f_buffer + nbytes;
  245. RtlFreeUnicodeString(&ucPath);
  246. CTEMemFree(LongerPath);
  247. return(pfile);
  248. }
  249. CTEMemFree(start);
  250. }
  251. ZwClose(handle);
  252. }
  253. RtlFreeUnicodeString(&ucPath);
  254. IF_DBG(NBT_DEBUG_LMHOST)
  255. KdPrint(("Nbt.LmOpenFile: ZwOpenFile(std) = %X\n", status));
  256. }
  257. CTEMemFree(LongerPath);
  258. }
  259. return((PLM_FILE) NULL);
  260. } // LmOpenFile