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.

421 lines
8.0 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. nullio.c
  5. Abstract:
  6. This module implements io on the 'null' device. It's pretty
  7. simple.
  8. Author:
  9. Matthew Bradburn (mattbr) 01-Aug-1995
  10. Revision History:
  11. --*/
  12. #include <sys/stat.h>
  13. #include <time.h>
  14. #include <wchar.h>
  15. #include "psxsrv.h"
  16. BOOLEAN
  17. NullOpen(
  18. IN PPSX_PROCESS p,
  19. IN PFILEDESCRIPTOR Fd,
  20. IN OUT PPSX_API_MSG m
  21. );
  22. BOOLEAN
  23. NullRead(
  24. IN PPSX_PROCESS p,
  25. IN OUT PPSX_API_MSG m,
  26. IN PFILEDESCRIPTOR Fd
  27. );
  28. BOOLEAN
  29. NullWrite(
  30. IN PPSX_PROCESS p,
  31. IN OUT PPSX_API_MSG m,
  32. IN PFILEDESCRIPTOR Fd
  33. );
  34. BOOLEAN
  35. NullDup(
  36. IN PPSX_PROCESS p,
  37. IN OUT PPSX_API_MSG m,
  38. IN PFILEDESCRIPTOR Fd,
  39. IN PFILEDESCRIPTOR FdDup
  40. );
  41. BOOLEAN
  42. NullLseek(
  43. IN PPSX_PROCESS p,
  44. IN OUT PPSX_API_MSG m,
  45. IN PFILEDESCRIPTOR Fd
  46. );
  47. BOOLEAN
  48. NullStat(
  49. IN PIONODE IoNode,
  50. IN HANDLE FileHandle,
  51. OUT struct stat *StatBuf,
  52. OUT NTSTATUS *pStatus
  53. );
  54. void
  55. FindOwnerModeFile(
  56. IN HANDLE FileHandle,
  57. OUT struct stat *StatBuf
  58. );
  59. PSXIO_VECTORS NullVectors = {
  60. NullOpen, // OpenNewHandle
  61. NULL, // NewHandle
  62. NULL, // Close
  63. NULL, // LastClose
  64. NULL, // IoNodeClose
  65. NullRead, // Read
  66. NullWrite, // Write
  67. NullDup, // Dup
  68. NullLseek, // Lseek
  69. NullStat // Stat
  70. };
  71. BOOLEAN
  72. NullOpen(
  73. IN PPSX_PROCESS p,
  74. IN PFILEDESCRIPTOR Fd,
  75. IN OUT PPSX_API_MSG m
  76. )
  77. /*++
  78. Routine Description:
  79. This routine
  80. Arguments:
  81. Return Value:
  82. FALSE - Failure.
  83. TRUE - Success.
  84. --*/
  85. {
  86. PPSX_OPEN_MSG args;
  87. LARGE_INTEGER time;
  88. ULONG posix_time;
  89. args = &m->u.Open;
  90. NtQuerySystemTime(&time);
  91. if (!RtlTimeToSecondsSince1970(&time, &posix_time)) {
  92. posix_time = 0;
  93. }
  94. KdPrint(("Posix time: %x\n", posix_time));
  95. RtlEnterCriticalSection(&Fd->SystemOpenFileDesc->IoNode->IoNodeLock);
  96. Fd->SystemOpenFileDesc->IoNode->ModifyDataTime = posix_time;
  97. Fd->SystemOpenFileDesc->IoNode->ModifyIoNodeTime = posix_time;
  98. Fd->SystemOpenFileDesc->IoNode->AccessDataTime = posix_time;
  99. RtlLeaveCriticalSection(&Fd->SystemOpenFileDesc->IoNode->IoNodeLock);
  100. return TRUE;
  101. }
  102. BOOLEAN
  103. NullWrite(
  104. IN PPSX_PROCESS p,
  105. IN OUT PPSX_API_MSG m,
  106. IN PFILEDESCRIPTOR Fd
  107. )
  108. /*++
  109. Routine Description:
  110. This procedure implements write when the device being written
  111. is the null device. Writes to the null device succeed, and the
  112. data is discarded.
  113. Arguments:
  114. p - Supplies the address of the process making the call.
  115. m - Supplies the address of the message associated with the request.
  116. Fd - supplies the address of the file descriptor being written.
  117. Return Value:
  118. --*/
  119. {
  120. PPSX_WRITE_MSG args;
  121. LARGE_INTEGER time;
  122. ULONG posix_time;
  123. NTSTATUS st;
  124. args = &m->u.Write;
  125. if (args->Nbytes > 0) {
  126. //
  127. // Update the times for stat.
  128. //
  129. NtQuerySystemTime(&time);
  130. if (!RtlTimeToSecondsSince1970(&time, &posix_time)) {
  131. posix_time = 0;
  132. }
  133. RtlEnterCriticalSection(&Fd->SystemOpenFileDesc->IoNode->IoNodeLock);
  134. Fd->SystemOpenFileDesc->IoNode->ModifyDataTime = posix_time;
  135. Fd->SystemOpenFileDesc->IoNode->ModifyIoNodeTime = posix_time;
  136. RtlLeaveCriticalSection(&Fd->SystemOpenFileDesc->IoNode->IoNodeLock);
  137. }
  138. m->ReturnValue = args->Nbytes;
  139. return TRUE;
  140. }
  141. BOOLEAN
  142. NullRead(
  143. IN PPSX_PROCESS p,
  144. IN OUT PPSX_API_MSG m,
  145. IN PFILEDESCRIPTOR Fd
  146. )
  147. /*++
  148. Routine Description:
  149. This procedure implements read when the device being read
  150. is the null device. Reads from this device always return EOF.
  151. Arguments:
  152. p - Supplies the address of the process making the call.
  153. m - Supplies the address of the message associated with the request.
  154. Fd - supplies the address of the file descriptor being read.
  155. Return Value:
  156. --*/
  157. {
  158. PPSX_READ_MSG args;
  159. NTSTATUS st;
  160. LARGE_INTEGER ByteOffset;
  161. ULONG IoBufferSize;
  162. LARGE_INTEGER Time;
  163. ULONG posix_time;
  164. args = &m->u.Read;
  165. if (args->Nbytes > 0) {
  166. //
  167. // Update the access time on the ionode.
  168. //
  169. NtQuerySystemTime(&Time);
  170. if (!RtlTimeToSecondsSince1970(&Time, &posix_time)) {
  171. posix_time = 0;
  172. }
  173. RtlEnterCriticalSection(&Fd->SystemOpenFileDesc->IoNode->IoNodeLock);
  174. Fd->SystemOpenFileDesc->IoNode->AccessDataTime = posix_time;
  175. RtlLeaveCriticalSection(&Fd->SystemOpenFileDesc->IoNode->IoNodeLock);
  176. }
  177. m->ReturnValue = 0;
  178. return TRUE;
  179. }
  180. BOOLEAN
  181. NullDup(
  182. IN PPSX_PROCESS p,
  183. IN OUT PPSX_API_MSG m,
  184. IN PFILEDESCRIPTOR Fd,
  185. IN PFILEDESCRIPTOR FdDup
  186. )
  187. /*++
  188. Routine Description:
  189. This procedure implements dup and dup2.
  190. Arguments:
  191. p - Supplies the address of the process making the call.
  192. m - Supplies the address of the message associated with the request.
  193. Fd - supplies the address of the file descriptor being duplicated.
  194. FdDup - supplies the address of the duplicate file descriptor.
  195. Return Value:
  196. TRUE.
  197. --*/
  198. {
  199. PPSX_DUP_MSG args;
  200. args = &m->u.Dup;
  201. //
  202. // Copy contents of source file descriptor slot into new descriptor
  203. // Note that FD_CLOEXEC must be CLEAR on FdDup.
  204. //
  205. *FdDup = *Fd;
  206. FdDup->Flags &= ~PSX_FD_CLOSE_ON_EXEC;
  207. //
  208. // Increment reference count associated with the SystemOpenFile
  209. // descriptor for this file.
  210. //
  211. // Grab system open file lock
  212. RtlEnterCriticalSection(&SystemOpenFileLock);
  213. Fd->SystemOpenFileDesc->HandleCount++;
  214. RtlLeaveCriticalSection(&SystemOpenFileLock);
  215. return TRUE;
  216. }
  217. BOOLEAN
  218. NullLseek(
  219. IN PPSX_PROCESS p,
  220. IN OUT PPSX_API_MSG m,
  221. IN PFILEDESCRIPTOR Fd
  222. )
  223. /*++
  224. Routine Description:
  225. This procedure implements lseek when the device being seeked on
  226. is the null device. We allow these seeks, but they have no effect.
  227. Arguments:
  228. p - Supplies the address of the process making the call.
  229. m - Supplies the address of the message associated with the request.
  230. Fd - supplies the address of the file descriptor being seekd
  231. Return Value:
  232. TRUE
  233. --*/
  234. {
  235. PPSX_LSEEK_MSG args;
  236. NTSTATUS st;
  237. LARGE_INTEGER Offset, NewByteOffset;
  238. args = &m->u.Lseek;
  239. Offset = RtlConvertLongToLargeInteger(args->Offset);
  240. NewByteOffset = Offset;
  241. if (SEEK_CUR != args->Whence && SEEK_SET != args->Whence &&
  242. SEEK_END != args->Whence) {
  243. m->Error = EINVAL;
  244. return TRUE;
  245. }
  246. // Check for overflow. POSIX limited to arithmetic data type for off_t
  247. if (NewByteOffset.HighPart != 0 || (off_t)NewByteOffset.LowPart < 0) {
  248. m->Error = EINVAL;
  249. }
  250. return TRUE;
  251. }
  252. BOOLEAN
  253. NullStat(
  254. IN PIONODE IoNode,
  255. IN HANDLE FileHandle,
  256. OUT struct stat *StatBuf,
  257. OUT NTSTATUS *pStatus
  258. )
  259. /*++
  260. Routine Description:
  261. This procedure implements stat when the device being read
  262. is the null device.
  263. Arguments:
  264. IoNode - supplies a pointer to the ionode of the file for which stat is
  265. requested. NULL if no active Ionode entry.
  266. FileHandle - supplies the Nt file handle of the file .
  267. StatBuf - Supplies the address of the statbuf portion of the message
  268. associated with the request.
  269. Return Value:
  270. TRUE.
  271. --*/
  272. {
  273. IO_STATUS_BLOCK Iosb;
  274. //
  275. // First get the static information on the file from the ionode if
  276. // there is one (i.e. if the file currently open.
  277. // Open() sets the fields in the ionode.
  278. //
  279. if (NULL != IoNode) {
  280. StatBuf->st_mode = IoNode->Mode;
  281. StatBuf->st_ino = (ino_t)IoNode->FileSerialNumber;
  282. StatBuf->st_dev = IoNode->DeviceSerialNumber;
  283. StatBuf->st_atime = IoNode->AccessDataTime;
  284. StatBuf->st_ctime = IoNode->ModifyIoNodeTime;
  285. StatBuf->st_mtime = IoNode->ModifyDataTime;
  286. }
  287. StatBuf->st_uid = 0;
  288. StatBuf->st_gid = 0;
  289. StatBuf->st_size = 0;
  290. StatBuf->st_nlink = 1;
  291. return TRUE;
  292. }