fatdev.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982
  1. /*++
  2. Copyright (c) 2014 Minoca Corp.
  3. This file is licensed under the terms of the GNU General Public License
  4. version 3. Alternative licensing terms are available. Contact
  5. info@minocacorp.com for details. See the LICENSE file at the root of this
  6. project for complete licensing information.
  7. Module Name:
  8. fatdev.c
  9. Abstract:
  10. This module implements support for FAT disk I/O in the setup packet.
  11. Author:
  12. Evan Green 14-Apr-2014
  13. Environment:
  14. User
  15. --*/
  16. //
  17. // ------------------------------------------------------------------- Includes
  18. //
  19. #include <assert.h>
  20. #include <errno.h>
  21. #include <getopt.h>
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <sys/types.h>
  25. #include <time.h>
  26. #include "setup.h"
  27. //
  28. // ---------------------------------------------------------------- Definitions
  29. //
  30. //
  31. // ------------------------------------------------------ Data Type Definitions
  32. //
  33. typedef VOID FAT_IO_BUFFER, *PFAT_IO_BUFFER;
  34. /*++
  35. Structure Description:
  36. This structure defines an I/O buffer for the setup program.
  37. Members:
  38. Data - Stores a pointer to the I/O buffer's data buffer.
  39. Size - Stores the size of the memory buffer, in bytes.
  40. CurrentOffset - Stores the current offset into the I/O buffer. All I/O will
  41. begin at the current offset.
  42. --*/
  43. typedef struct _SETUP_FAT_IO_BUFFER {
  44. PVOID Data;
  45. UINTN Size;
  46. UINTN CurrentOffset;
  47. } SETUP_FAT_IO_BUFFER, *PSETUP_FAT_IO_BUFFER;
  48. //
  49. // ----------------------------------------------- Internal Function Prototypes
  50. //
  51. //
  52. // -------------------------------------------------------------------- Globals
  53. //
  54. //
  55. // ------------------------------------------------------------------ Functions
  56. //
  57. PFAT_IO_BUFFER
  58. FatAllocateIoBuffer (
  59. PVOID DeviceToken,
  60. UINTN Size
  61. )
  62. /*++
  63. Routine Description:
  64. This routine allocates memory for device I/O use.
  65. Arguments:
  66. DeviceToken - Supplies an opaque token identifying the underlying device.
  67. Size - Supplies the size of the required allocation, in bytes.
  68. Return Value:
  69. Returns a pointer to the FAT I/O buffer, or NULL on failure.
  70. --*/
  71. {
  72. PSETUP_FAT_IO_BUFFER IoBuffer;
  73. IoBuffer = malloc(sizeof(SETUP_FAT_IO_BUFFER) + Size);
  74. if (IoBuffer == NULL) {
  75. return NULL;
  76. }
  77. IoBuffer->Data = (PVOID)IoBuffer + sizeof(SETUP_FAT_IO_BUFFER);
  78. IoBuffer->Size = Size;
  79. IoBuffer->CurrentOffset = 0;
  80. return IoBuffer;
  81. }
  82. PFAT_IO_BUFFER
  83. FatCreateIoBuffer (
  84. PVOID Buffer,
  85. UINTN Size
  86. )
  87. /*++
  88. Routine Description:
  89. This routine creates a FAT I/O buffer from the given buffer.
  90. Arguments:
  91. Buffer - Supplies a pointer to the memory buffer on which to base the FAT
  92. I/O buffer.
  93. Size - Supplies the size of the memory buffer, in bytes.
  94. Return Value:
  95. Returns an pointer to the FAT I/O buffer, or NULL on failure.
  96. --*/
  97. {
  98. PSETUP_FAT_IO_BUFFER IoBuffer;
  99. IoBuffer = malloc(sizeof(SETUP_FAT_IO_BUFFER));
  100. if (IoBuffer == NULL) {
  101. return NULL;
  102. }
  103. IoBuffer->Data = Buffer;
  104. IoBuffer->Size = Size;
  105. IoBuffer->CurrentOffset = 0;
  106. return IoBuffer;
  107. }
  108. VOID
  109. FatIoBufferUpdateOffset (
  110. PFAT_IO_BUFFER FatIoBuffer,
  111. UINTN OffsetUpdate,
  112. BOOL Decrement
  113. )
  114. /*++
  115. Routine Description:
  116. This routine increments the given FAT I/O buffer's current offset by the
  117. given amount.
  118. Arguments:
  119. FatIoBuffer - Supplies a pointer to a FAT I/O buffer.
  120. OffsetUpdate - Supplies the number of bytes by which the offset will be
  121. updated.
  122. Decrement - Supplies a boolean indicating whether the update will be a
  123. decrement (TRUE) or an increment (FALSE).
  124. Return Value:
  125. None.
  126. --*/
  127. {
  128. if (Decrement == FALSE) {
  129. ((PSETUP_FAT_IO_BUFFER)FatIoBuffer)->CurrentOffset += OffsetUpdate;
  130. } else {
  131. ((PSETUP_FAT_IO_BUFFER)FatIoBuffer)->CurrentOffset -= OffsetUpdate;
  132. }
  133. ASSERT(((PSETUP_FAT_IO_BUFFER)FatIoBuffer)->CurrentOffset <=
  134. ((PSETUP_FAT_IO_BUFFER)FatIoBuffer)->Size);
  135. return;
  136. }
  137. VOID
  138. FatIoBufferSetOffset (
  139. PFAT_IO_BUFFER FatIoBuffer,
  140. UINTN Offset
  141. )
  142. /*++
  143. Routine Description:
  144. This routine sets the given FAT I/O buffer's current offset.
  145. Arguments:
  146. FatIoBuffer - Supplies a pointer to a FAT I/O buffer.
  147. Offset - Supplies the new offset to set.
  148. Return Value:
  149. None.
  150. --*/
  151. {
  152. PSETUP_FAT_IO_BUFFER IoBuffer;
  153. IoBuffer = (PSETUP_FAT_IO_BUFFER)FatIoBuffer;
  154. IoBuffer->CurrentOffset = Offset;
  155. ASSERT(IoBuffer->CurrentOffset <= IoBuffer->Size);
  156. return;
  157. }
  158. KSTATUS
  159. FatZeroIoBuffer (
  160. PFAT_IO_BUFFER FatIoBuffer,
  161. UINTN Offset,
  162. UINTN ByteCount
  163. )
  164. /*++
  165. Routine Description:
  166. This routine zeros the contents of the FAT I/O buffer starting at the
  167. offset for the given number of bytes.
  168. Arguments:
  169. FatIoBuffer - Supplies a pointer to the FAT I/O buffer that is to be zeroed.
  170. Offset - Supplies the offset within the I/O buffer where the zeroing should
  171. begin.
  172. ByteCount - Supplies the number of bytes to zero.
  173. Return Value:
  174. Status code.
  175. --*/
  176. {
  177. PSETUP_FAT_IO_BUFFER IoBuffer;
  178. IoBuffer = (PSETUP_FAT_IO_BUFFER)FatIoBuffer;
  179. RtlZeroMemory(IoBuffer->Data + IoBuffer->CurrentOffset + Offset, ByteCount);
  180. return STATUS_SUCCESS;
  181. }
  182. KSTATUS
  183. FatCopyIoBuffer (
  184. PFAT_IO_BUFFER Destination,
  185. UINTN DestinationOffset,
  186. PFAT_IO_BUFFER Source,
  187. UINTN SourceOffset,
  188. UINTN ByteCount
  189. )
  190. /*++
  191. Routine Description:
  192. This routine copies the contents of the source I/O buffer starting at the
  193. source offset to the destination I/O buffer starting at the destination
  194. offset. It assumes that the arguments are correct such that the copy can
  195. succeed.
  196. Arguments:
  197. Destination - Supplies a pointer to the destination I/O buffer that is to
  198. be copied into.
  199. DestinationOffset - Supplies the offset into the destination I/O buffer
  200. where the copy should begin.
  201. Source - Supplies a pointer to the source I/O buffer whose contents will be
  202. copied to the destination.
  203. SourceOffset - Supplies the offset into the source I/O buffer where the
  204. copy should begin.
  205. ByteCount - Supplies the size of the requested copy in bytes.
  206. Return Value:
  207. Status code.
  208. --*/
  209. {
  210. PVOID DestinationBuffer;
  211. PSETUP_FAT_IO_BUFFER DestinationIoBuffer;
  212. PVOID SourceBuffer;
  213. PSETUP_FAT_IO_BUFFER SourceIoBuffer;
  214. DestinationIoBuffer = (PSETUP_FAT_IO_BUFFER)Destination;
  215. DestinationBuffer = DestinationIoBuffer->Data +
  216. DestinationIoBuffer->CurrentOffset +
  217. DestinationOffset;
  218. SourceIoBuffer = (PSETUP_FAT_IO_BUFFER)Source;
  219. SourceBuffer = SourceIoBuffer->Data +
  220. SourceIoBuffer->CurrentOffset +
  221. SourceOffset;
  222. RtlCopyMemory(DestinationBuffer, SourceBuffer, ByteCount);
  223. return STATUS_SUCCESS;
  224. }
  225. KSTATUS
  226. FatCopyIoBufferData (
  227. PFAT_IO_BUFFER FatIoBuffer,
  228. PVOID Buffer,
  229. UINTN Offset,
  230. UINTN Size,
  231. BOOL ToIoBuffer
  232. )
  233. /*++
  234. Routine Description:
  235. This routine copies from a buffer into the given I/O buffer or out of the
  236. given I/O buffer.
  237. Arguments:
  238. FatIoBuffer - Supplies a pointer to the FAT I/O buffer to copy in or out of.
  239. Buffer - Supplies a pointer to the regular linear buffer to copy to or from.
  240. Offset - Supplies an offset in bytes from the beginning of the I/O buffer
  241. to copy to or from.
  242. Size - Supplies the number of bytes to copy.
  243. ToIoBuffer - Supplies a boolean indicating whether data is copied into the
  244. I/O buffer (TRUE) or out of the I/O buffer (FALSE).
  245. Return Value:
  246. Status code.
  247. --*/
  248. {
  249. PVOID Destination;
  250. PSETUP_FAT_IO_BUFFER IoBuffer;
  251. PVOID Source;
  252. IoBuffer = (PSETUP_FAT_IO_BUFFER)FatIoBuffer;
  253. ASSERT(IoBuffer->CurrentOffset + Offset + Size <= IoBuffer->Size);
  254. Destination = IoBuffer->Data + IoBuffer->CurrentOffset + Offset;
  255. Source = Buffer;
  256. if (ToIoBuffer == FALSE) {
  257. Source = Destination;
  258. Destination = Buffer;
  259. }
  260. RtlCopyMemory(Destination, Source, Size);
  261. return STATUS_SUCCESS;
  262. }
  263. PVOID
  264. FatMapIoBuffer (
  265. PFAT_IO_BUFFER FatIoBuffer
  266. )
  267. /*++
  268. Routine Description:
  269. This routine maps the given FAT I/O buffer and returns the base of the
  270. virtually contiguous mapping.
  271. Arguments:
  272. FatIoBuffer - Supplies a pointer to a FAT I/O buffer.
  273. Return Value:
  274. Returns a pointer to the virtual address of the mapping on success, or
  275. NULL on failure.
  276. --*/
  277. {
  278. return ((PSETUP_FAT_IO_BUFFER)FatIoBuffer)->Data;
  279. }
  280. VOID
  281. FatFreeIoBuffer (
  282. PFAT_IO_BUFFER FatIoBuffer
  283. )
  284. /*++
  285. Routine Description:
  286. This routine frees a FAT I/O buffer.
  287. Arguments:
  288. FatIoBuffer - Supplies a pointer to a FAT I/O buffer.
  289. Return Value:
  290. None.
  291. --*/
  292. {
  293. free(FatIoBuffer);
  294. return;
  295. }
  296. PVOID
  297. FatAllocatePagedMemory (
  298. PVOID DeviceToken,
  299. ULONG SizeInBytes
  300. )
  301. /*++
  302. Routine Description:
  303. This routine allocates paged memory for the FAT library.
  304. Arguments:
  305. DeviceToken - Supplies an opaque token identifying the underlying device.
  306. SizeInBytes - Supplies the number of bytes to allocate.
  307. Return Value:
  308. Returns a pointer to the allocated memory, or NULL on failure.
  309. --*/
  310. {
  311. return malloc(SizeInBytes);
  312. }
  313. PVOID
  314. FatAllocateNonPagedMemory (
  315. PVOID DeviceToken,
  316. ULONG SizeInBytes
  317. )
  318. /*++
  319. Routine Description:
  320. This routine allocates non-paged memory for the FAT library.
  321. Arguments:
  322. DeviceToken - Supplies an opaque token identifying the underlying device.
  323. SizeInBytes - Supplies the number of bytes to allocate.
  324. Return Value:
  325. Returns a pointer to the allocated memory, or NULL on failure.
  326. --*/
  327. {
  328. return malloc(SizeInBytes);
  329. }
  330. VOID
  331. FatFreePagedMemory (
  332. PVOID DeviceToken,
  333. PVOID Allocation
  334. )
  335. /*++
  336. Routine Description:
  337. This routine frees paged memory for the FAT library.
  338. Arguments:
  339. DeviceToken - Supplies an opaque token identifying the underlying device.
  340. Allocation - Supplies a pointer to the allocation to free.
  341. Return Value:
  342. None.
  343. --*/
  344. {
  345. free(Allocation);
  346. return;
  347. }
  348. VOID
  349. FatFreeNonPagedMemory (
  350. PVOID DeviceToken,
  351. PVOID Allocation
  352. )
  353. /*++
  354. Routine Description:
  355. This routine frees memory for the FAT library.
  356. Arguments:
  357. DeviceToken - Supplies an opaque token identifying the underlying device.
  358. Allocation - Supplies a pointer to the allocation to free.
  359. Return Value:
  360. None.
  361. --*/
  362. {
  363. free(Allocation);
  364. return;
  365. }
  366. KSTATUS
  367. FatCreateLock (
  368. PVOID *Lock
  369. )
  370. /*++
  371. Routine Description:
  372. This routine creates a lock.
  373. Arguments:
  374. Lock - Supplies a pointer where an opaque pointer will be returned
  375. representing the lock.
  376. Return Value:
  377. STATUS_SUCCESS on success.
  378. STATUS_INSUFFICIENT_RESOURCES if the lock could not be allocated.
  379. --*/
  380. {
  381. *Lock = NULL;
  382. return STATUS_SUCCESS;
  383. }
  384. VOID
  385. FatDestroyLock (
  386. PVOID Lock
  387. )
  388. /*++
  389. Routine Description:
  390. This routine destroys a created lock.
  391. Arguments:
  392. Lock - Supplies a the opaque pointer returned upon creation.
  393. Return Value:
  394. None.
  395. --*/
  396. {
  397. return;
  398. }
  399. VOID
  400. FatAcquireLock (
  401. PVOID Lock
  402. )
  403. /*++
  404. Routine Description:
  405. This routine acquires a lock.
  406. Arguments:
  407. Lock - Supplies a the opaque pointer returned upon creation.
  408. Return Value:
  409. None.
  410. --*/
  411. {
  412. return;
  413. }
  414. VOID
  415. FatReleaseLock (
  416. PVOID Lock
  417. )
  418. /*++
  419. Routine Description:
  420. This routine releases a lock.
  421. Arguments:
  422. Lock - Supplies a the opaque pointer returned upon creation.
  423. Return Value:
  424. None.
  425. --*/
  426. {
  427. return;
  428. }
  429. KSTATUS
  430. FatReadDevice (
  431. PVOID DeviceToken,
  432. ULONGLONG BlockAddress,
  433. UINTN BlockCount,
  434. ULONG Flags,
  435. PVOID Irp,
  436. PFAT_IO_BUFFER *FatIoBuffer
  437. )
  438. /*++
  439. Routine Description:
  440. This routine reads data from the underlying disk.
  441. Arguments:
  442. DeviceToken - Supplies an opaque token identifying the underlying device.
  443. BlockAddress - Supplies the block index to read (for physical disks, this is
  444. the LBA).
  445. BlockCount - Supplies the number of blocks to read.
  446. Flags - Supplies flags regarding the I/O operation. See IO_FLAG_*
  447. definitions.
  448. Irp - Supplies an optional pointer to the IRP to pass to the read file
  449. function.
  450. FatIoBuffer - Supplies a pointer to a FAT I/O buffer where the data from
  451. the disk will be returned.
  452. Return Value:
  453. Status code.
  454. --*/
  455. {
  456. PVOID Buffer;
  457. size_t ByteCount;
  458. ssize_t BytesRead;
  459. PSETUP_CONTEXT Context;
  460. PSETUP_FAT_IO_BUFFER IoBuffer;
  461. KSTATUS Status;
  462. PSETUP_VOLUME Volume;
  463. assert(SETUP_BLOCK_SIZE != 0);
  464. assert(FatIoBuffer != NULL);
  465. Volume = DeviceToken;
  466. Context = Volume->Context;
  467. IoBuffer = (PSETUP_FAT_IO_BUFFER)FatIoBuffer;
  468. Buffer = IoBuffer->Data + IoBuffer->CurrentOffset;
  469. ByteCount = BlockCount * SETUP_BLOCK_SIZE;
  470. assert((IoBuffer->Size - IoBuffer->CurrentOffset) >= ByteCount);
  471. if ((Volume->DestinationType == SetupDestinationPartition) ||
  472. (Volume->DestinationType == SetupDestinationDisk)) {
  473. SetupPartitionSeek(Context, Volume->BlockHandle, BlockAddress);
  474. BytesRead = SetupPartitionRead(Context,
  475. Volume->BlockHandle,
  476. Buffer,
  477. ByteCount);
  478. } else {
  479. SetupSeek(Volume->BlockHandle, BlockAddress * SETUP_BLOCK_SIZE);
  480. BytesRead = SetupRead(Volume->BlockHandle, Buffer, ByteCount);
  481. }
  482. if (BytesRead != ByteCount) {
  483. Status = STATUS_DEVICE_IO_ERROR;
  484. goto ReadDeviceEnd;
  485. }
  486. Status = STATUS_SUCCESS;
  487. ReadDeviceEnd:
  488. if (!KSUCCESS(Status)) {
  489. printf("Failed to read FAT device: %d\n", Status);
  490. }
  491. return Status;
  492. }
  493. KSTATUS
  494. FatWriteDevice (
  495. PVOID DeviceToken,
  496. ULONGLONG BlockAddress,
  497. UINTN BlockCount,
  498. ULONG Flags,
  499. PVOID Irp,
  500. PFAT_IO_BUFFER FatIoBuffer
  501. )
  502. /*++
  503. Routine Description:
  504. This routine writes data to the underlying disk.
  505. Arguments:
  506. DeviceToken - Supplies an opaque token identifying the underlying device.
  507. BlockAddress - Supplies the block index to write to (for physical disks,
  508. this is the LBA).
  509. BlockCount - Supplies the number of blocks to write.
  510. Flags - Supplies flags regarding the I/O operation. See IO_FLAG_*
  511. definitions.
  512. Irp - Supplies an optional pointer to an IRP to use for the disk operation.
  513. FatIoBuffer - Supplies a pointer to a FAT I/O buffer containing the data to
  514. write.
  515. Return Value:
  516. Status code.
  517. --*/
  518. {
  519. ULONG BlockSize;
  520. PVOID Buffer;
  521. ssize_t BytesWritten;
  522. PSETUP_CONTEXT Context;
  523. PSETUP_FAT_IO_BUFFER SetupIoBuffer;
  524. KSTATUS Status;
  525. PSETUP_VOLUME Volume;
  526. Volume = DeviceToken;
  527. Context = Volume->Context;
  528. BlockSize = SETUP_BLOCK_SIZE;
  529. assert(BlockSize != 0);
  530. SetupIoBuffer = (PSETUP_FAT_IO_BUFFER)FatIoBuffer;
  531. Buffer = SetupIoBuffer->Data + SetupIoBuffer->CurrentOffset;
  532. if ((Volume->DestinationType == SetupDestinationPartition) ||
  533. (Volume->DestinationType == SetupDestinationDisk)) {
  534. SetupPartitionSeek(Context, Volume->BlockHandle, BlockAddress);
  535. BytesWritten = SetupPartitionWrite(Context,
  536. Volume->BlockHandle,
  537. Buffer,
  538. BlockCount * BlockSize);
  539. } else {
  540. SetupSeek(Volume->BlockHandle, BlockAddress * BlockSize);
  541. BytesWritten = SetupWrite(Volume->BlockHandle,
  542. Buffer,
  543. BlockCount * BlockSize);
  544. }
  545. if (BytesWritten != BlockCount * BlockSize) {
  546. Status = STATUS_DEVICE_IO_ERROR;
  547. goto WriteDeviceEnd;
  548. }
  549. Status = STATUS_SUCCESS;
  550. WriteDeviceEnd:
  551. if (!KSUCCESS(Status)) {
  552. printf("Failed to write FAT device: %d\n", Status);
  553. }
  554. return Status;
  555. }
  556. KSTATUS
  557. FatGetDeviceBlockInformation (
  558. PVOID DeviceToken,
  559. PFILE_BLOCK_INFORMATION BlockInformation
  560. )
  561. /*++
  562. Routine Description:
  563. This routine converts a file's block information into disk level block
  564. information by modifying the offsets of each contiguous run.
  565. Arguments:
  566. DeviceToken - Supplies an opaque token identify the underlying device.
  567. BlockInformation - Supplies a pointer to the block information to be
  568. updated.
  569. Return Value:
  570. Status code.
  571. --*/
  572. {
  573. ASSERT(FALSE);
  574. return STATUS_NOT_IMPLEMENTED;
  575. }
  576. ULONG
  577. FatGetIoCacheEntryDataSize (
  578. VOID
  579. )
  580. /*++
  581. Routine Description:
  582. This routine returns the size of data stored in each cache entry.
  583. Arguments:
  584. None.
  585. Return Value:
  586. Returns the size of the data stored in each cache entry, or 0 if there is
  587. no cache.
  588. --*/
  589. {
  590. return 0;
  591. }
  592. ULONG
  593. FatGetPageSize (
  594. VOID
  595. )
  596. /*++
  597. Routine Description:
  598. This routine returns the size of a physical memory page for the current FAT
  599. environment.
  600. Arguments:
  601. None.
  602. Return Value:
  603. Returns the size of a page in the current environment. Returns 0 if the
  604. size is not known.
  605. --*/
  606. {
  607. return 0;
  608. }
  609. VOID
  610. FatGetCurrentSystemTime (
  611. PSYSTEM_TIME SystemTime
  612. )
  613. /*++
  614. Routine Description:
  615. This routine returns the current system time.
  616. Arguments:
  617. SystemTime - Supplies a pointer where the current system time will be
  618. returned.
  619. Return Value:
  620. None.
  621. --*/
  622. {
  623. SystemTime->Seconds = (LONGLONG)time(NULL) - SYSTEM_TIME_TO_EPOCH_DELTA;
  624. SystemTime->Nanoseconds = 0;
  625. return;
  626. }
  627. //
  628. // --------------------------------------------------------- Internal Functions
  629. //