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.

759 lines
20 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. NpStruc.h
  5. Abstract:
  6. This module defines the data structures that make up the major internal
  7. part of the Named Pipe file system.
  8. Author:
  9. Gary Kimura [GaryKi] 20-Aug-1990
  10. Revision History:
  11. --*/
  12. #ifndef _NPSTRUC_
  13. #define _NPSTRUC_
  14. //
  15. // The VCB record is the top record in the Named Pipe file system in-memory
  16. // data structure. This structure must be allocated from non-paged pool
  17. // and immediately follows (in memory) the Device object for the named
  18. // pipe. Structurally the layout of the data structure is as follows
  19. //
  20. // +------------+
  21. // |NPDO |
  22. // | |
  23. // +------------+
  24. // |Vcb |
  25. // | |
  26. // | EventTable |
  27. // | WaitQueue |
  28. // | |
  29. // +------------+
  30. // | ^
  31. // | |
  32. // | |
  33. // v |
  34. // +-------------+
  35. // |RootDcb |
  36. // | |<-+
  37. // +-------------+ |
  38. // | |
  39. // v |
  40. // +-------------+ |
  41. // |NonPaged | |
  42. // | | |
  43. // +-------------+ |
  44. // : |
  45. // : |
  46. // : |
  47. // v |
  48. // +----------------+ +-------------------+ +---------+
  49. // |Fcb | |Ccb | |ServerFO |
  50. // | |<---| | | |
  51. // | MaxInstances | | ServerFO |<-------|- 1|
  52. // | CurrentInst | | ClientFO | | |
  53. // | DefaultTimeOut |...>| |<-+ +--|- |
  54. // | | | | | | | |
  55. // +----------------+ +-------------------+ | | +---------+
  56. // | | | |
  57. // v v | |
  58. // +----------------+ +-------------------+ | | +---------+
  59. // |NonPagedFcb | |NonPagedCcb |<-|--+ |ClientFO |
  60. // | |<---| | | | |
  61. // | PipeConfig | | PipeState | +-----|- 0|
  62. // | PipeType | | ReadMode[2] | | |
  63. // | | | CompletionMode[2] |<-------|- |
  64. // | | | CreatorProcess | | |
  65. // | | | EventTabEnt[2] | +---------+
  66. // | | | DataQueue[2] |
  67. // | | | | (low bit determines
  68. // +----------------+ +-------------------+ server/client)
  69. //
  70. //
  71. // Where there is only one Vcb for the entire Named Pipe file system, and
  72. // it contains a single pointer to the root dcb for the file system. Off
  73. // of the Dcb is a queue of Fcb's. There is one Fcb for every named pipe.
  74. // There is one Ccb for every instance of a named pipe. There are also
  75. // two additional ccb types for the vcb and the root dcb, and notify records
  76. // for the notify change operations.
  77. //
  78. // A newly initialized named pipe file system only contains the Vcb and
  79. // the root dcb. A new Fcb is created when a new named pipe is created
  80. // and then a ccb must also be created. The file object for the creater
  81. // (i.e., server end) points to the ccb and indicates that it is the server
  82. // end. When a user does an open on the named pipe its file object is
  83. // set to point to the same ccb and is also set to indicate that it is the
  84. // client end. This is denoted by using the last bit of the FsContext pointer
  85. // if the bit is 1 it is a server end file object, if the bit is 0 it is
  86. // the client end.
  87. //
  88. // A file object with a null pointer to the FsContext field is a closed or
  89. // disconnected pipe.
  90. //
  91. // The Ccb also contains back pointer to the file objects that have it opened
  92. //
  93. //
  94. // The following types are used to help during development by keeping the
  95. // data types distinct. The manifest contants that go in each is declared
  96. // in the ntioapi.h file
  97. //
  98. typedef ULONG NAMED_PIPE_TYPE;
  99. typedef NAMED_PIPE_TYPE *PNAMED_PIPE_TYPE;
  100. typedef ULONG READ_MODE;
  101. typedef READ_MODE *PREAD_MODE;
  102. typedef ULONG COMPLETION_MODE;
  103. typedef COMPLETION_MODE *PCOMPLETION_MODE;
  104. typedef ULONG NAMED_PIPE_CONFIGURATION;
  105. typedef NAMED_PIPE_CONFIGURATION *PNAMED_PIPE_CONFIGURATION;
  106. typedef ULONG NAMED_PIPE_STATE;
  107. typedef NAMED_PIPE_STATE *PNAMED_PIPE_STATE;
  108. typedef ULONG NAMED_PIPE_END;
  109. typedef NAMED_PIPE_END *PNAMED_PIPE_END;
  110. //
  111. // The following two types are used by the event table package. The first
  112. // is the event table itself which is just a generic table. It is protected
  113. // by the vcb resource, and the second structure is an event table entry.
  114. //
  115. typedef struct _EVENT_TABLE {
  116. RTL_GENERIC_TABLE Table;
  117. } EVENT_TABLE;
  118. typedef EVENT_TABLE *PEVENT_TABLE;
  119. //
  120. // The event table is a generic table of event table entries. Each Ccb
  121. // optionally contains a pointer to an event table entry for each direction.
  122. // The entries are part of the global event table defined off of the Vcb
  123. //
  124. typedef struct _EVENT_TABLE_ENTRY {
  125. //
  126. // The first two fields are used as keys in the generic table's
  127. // comparison routines. The pipe end will either be FILE_PIPE_CLIENT_END
  128. // or FILE_PIPE_SERVER_END.
  129. //
  130. struct _CCB *Ccb;
  131. NAMED_PIPE_END NamedPipeEnd;
  132. //
  133. // The following three fields are used to identify the event entry
  134. // to the named pipe user
  135. //
  136. HANDLE EventHandle;
  137. PVOID Event;
  138. ULONG KeyValue;
  139. PEPROCESS Process;
  140. } EVENT_TABLE_ENTRY;
  141. typedef EVENT_TABLE_ENTRY *PEVENT_TABLE_ENTRY;
  142. //
  143. // Each Ccb has two data queues for holding the outstanding in-bound and
  144. // out-bound read/write requests. The following type is used to determine
  145. // if the data queue contains read requests, write requests, or is empty.
  146. //
  147. typedef enum _QUEUE_STATE {
  148. ReadEntries,
  149. WriteEntries,
  150. Empty
  151. } QUEUE_STATE;
  152. //
  153. // The data queue is a structure that contains the queue state, quota
  154. // information, and the list head. The quota information is used to
  155. // maintain pipe quota.
  156. //
  157. typedef struct _DATA_QUEUE {
  158. //
  159. // This is the head of a queue of data entries (singly linked)
  160. //
  161. LIST_ENTRY Queue;
  162. //
  163. // The current state of what is contained in this data queue,
  164. // how many bytes of read/write data there are, and how many individual
  165. // requests there are in the queue that contain data (includes
  166. // close or flush requests).
  167. //
  168. QUEUE_STATE QueueState;
  169. ULONG BytesInQueue;
  170. ULONG EntriesInQueue;
  171. //
  172. // The following two fields denote who much quota was reserved for
  173. // this pipe direction and how much we've used up. This is only
  174. // the creator quota and not the user quota.
  175. //
  176. ULONG Quota;
  177. ULONG QuotaUsed;
  178. //
  179. // The following field indicates how far we've already processed
  180. // into the first entry in the data queue
  181. //
  182. ULONG NextByteOffset;
  183. } DATA_QUEUE;
  184. typedef DATA_QUEUE *PDATA_QUEUE;
  185. //
  186. // Each data entry has a type field that tells us if the operation
  187. // for the entry is buffered, unbuffered, flush, or a close entry.
  188. //
  189. typedef enum _DATA_ENTRY_TYPE {
  190. Buffered,
  191. Unbuffered,
  192. Flush,
  193. Close
  194. } DATA_ENTRY_TYPE;
  195. //
  196. // The following type is used to denote where we got the memory for the
  197. // data entry and possibly the data buffer. We either got the memory
  198. // from the pipe quota, the user quota, or it is part of the next IRP stack
  199. // location.
  200. //
  201. typedef enum _FROM {
  202. PipeQuota,
  203. UserQuota,
  204. InIrp
  205. } FROM;
  206. //
  207. // Each entry in the data queue is a data entry. Processing an IRP
  208. // has the potential of creating and inserting a new data entry. If the
  209. // memory for the entry is taken from the IRP we use the next stack
  210. // location.
  211. //
  212. typedef struct _DATA_ENTRY {
  213. //
  214. // The following field is how we connect into the queue of data entries
  215. //
  216. LIST_ENTRY Queue;
  217. //
  218. // The following field indicates if we still have an IRP associated
  219. // with this data entry that need to be completed when the remove
  220. // the data entry. Note that if From is InIrp that this IRP field
  221. // must not be null.
  222. //
  223. PIRP Irp;
  224. //
  225. // The following field is used to point to the client context if dynamic
  226. // impersonation is being used
  227. //
  228. PSECURITY_CLIENT_CONTEXT SecurityClientContext;
  229. //
  230. // The following field describe the type of data entry
  231. //
  232. ULONG DataEntryType;
  233. //
  234. // Record the amount of quota charged for this request.
  235. //
  236. ULONG QuotaCharged;
  237. //
  238. // The following field describes the size of the data
  239. // buffer described by this entry.
  240. //
  241. ULONG DataSize;
  242. //
  243. // Start of the data buffer if it exists
  244. //
  245. UCHAR DataBuffer[];
  246. } DATA_ENTRY;
  247. typedef DATA_ENTRY *PDATA_ENTRY;
  248. //
  249. // The following type is used by the wait queue package
  250. //
  251. typedef struct _WAIT_QUEUE {
  252. LIST_ENTRY Queue;
  253. KSPIN_LOCK SpinLock;
  254. } WAIT_QUEUE;
  255. typedef WAIT_QUEUE *PWAIT_QUEUE;
  256. typedef struct _VCB {
  257. //
  258. // The type of this record (must be NPFS_NTC_VCB)
  259. //
  260. NODE_TYPE_CODE NodeTypeCode;
  261. //
  262. // The following field is used to check share access people who want
  263. // to open the named pipe driver
  264. //
  265. SHARE_ACCESS ShareAccess;
  266. //
  267. // A pointer to the root DCB for this volume
  268. //
  269. struct _FCB *RootDcb;
  270. //
  271. // A count of the number of file objects that have opened the \NamedPipe
  272. // object directly, and also a count of the number of file objects
  273. // that have opened a name pipe or the root directory.
  274. //
  275. CLONG OpenCount;
  276. //
  277. // A prefix table that is used for quick, prefix directed, lookup of
  278. // FCBs/DCBs that are part of this volume
  279. //
  280. UNICODE_PREFIX_TABLE PrefixTable;
  281. //
  282. // A resource variable to control access to the volume specific data
  283. // structures
  284. //
  285. ERESOURCE Resource;
  286. //
  287. // The following table is used to hold the named pipe events
  288. //
  289. EVENT_TABLE EventTable;
  290. //
  291. // The following field is a queue of waiting IRPS of type WaitForNamedPipe
  292. //
  293. WAIT_QUEUE WaitQueue;
  294. } VCB;
  295. typedef VCB *PVCB;
  296. //
  297. // The Named Pipe Device Object is an I/O system device object with
  298. // additional workqueue parameters appended to the end. There is only
  299. // one of these records created for the entire system during system
  300. // initialization.
  301. //
  302. typedef struct _NPFS_DEVICE_OBJECT {
  303. DEVICE_OBJECT DeviceObject;
  304. //
  305. // This is the file system specific volume control block.
  306. //
  307. VCB Vcb;
  308. } NPFS_DEVICE_OBJECT;
  309. typedef NPFS_DEVICE_OBJECT *PNPFS_DEVICE_OBJECT;
  310. //
  311. // The Fcb/Dcb record corresponds to every opened named pipe and directory,
  312. // and to every directory on an opened path.
  313. //
  314. // The structure is really divided into two parts. FCB can be allocated
  315. // from paged pool which the NONPAGED_FCB must be allocated from non-paged
  316. // pool.
  317. //
  318. typedef struct _FCB {
  319. //
  320. // Type of this record (must be NPFS_NTC_FCB, or
  321. // NPFS_NTC_ROOT_DCB)
  322. //
  323. NODE_TYPE_CODE NodeTypeCode;
  324. //
  325. // The links for the queue of all fcbs for a specific dcb off of
  326. // Dcb.ParentDcbQueue. For the root directory this queue is empty
  327. //
  328. LIST_ENTRY ParentDcbLinks;
  329. //
  330. // A pointer to the Dcb that is the parent directory containing
  331. // this fcb. If this record itself is the root dcb then this field
  332. // is null.
  333. //
  334. struct _FCB *ParentDcb;
  335. //
  336. // A pointer to the Vcb containing this fcb
  337. //
  338. PVCB Vcb;
  339. //
  340. // A count of the number of file objects that have opened
  341. // this file/directory. For a pipe this is also the number of instances
  342. // created for the pipe.
  343. //
  344. CLONG OpenCount;
  345. //
  346. // A count of the number of server end file objects that have opened
  347. // this pipe. ServerOpenCount is incremented when OpenCount is
  348. // incremented (when the server end creates an instance), but is
  349. // decremented when the server end handle is closed, where OpenCount
  350. // isn't decremented until both side's handles are closed. When
  351. // ServerOpenCount is 0, a client's attempt to open a named pipe is
  352. // met with STATUS_OBJECT_NAME_NOT_FOUND, not STATUS_PIPE_NOT_AVAILABLE,
  353. // based on an assumption that since the server doesn't think it has
  354. // any instances open, the pipe really doesn't exist anymore. An
  355. // example of when this distinction is useful is when the server
  356. // process exits, but the client processes haven't closed their
  357. // handles yet.
  358. //
  359. CLONG ServerOpenCount;
  360. //
  361. // The following field points to the security descriptor for this named pipe
  362. //
  363. PSECURITY_DESCRIPTOR SecurityDescriptor;
  364. //
  365. // The following union is cased off of the node type code for the fcb.
  366. // There is a seperate case for the directory versus file fcbs.
  367. //
  368. union {
  369. //
  370. // A Directory Control Block (Dcb)
  371. //
  372. struct {
  373. //
  374. // A queue of the notify IRPs that will be completed when any
  375. // change is made to a file in the directory. Enqueued using
  376. // the Tail.Overlay.ListEntry of the Irp.
  377. //
  378. LIST_ENTRY NotifyFullQueue;
  379. //
  380. // A queue of the notify IRPs that will be completed only if a
  381. // file is added, deleted, or renamed in the directory. Enqueued
  382. // using the Tail.Overlay.ListEntry of the Irp.
  383. //
  384. LIST_ENTRY NotifyPartialQueue;
  385. //
  386. // A queue of all the fcbs/dcbs that are opened under this
  387. // Dcb.
  388. //
  389. LIST_ENTRY ParentDcbQueue;
  390. //
  391. // The following field is used to check share access people
  392. // who want to open the directory.
  393. //
  394. SHARE_ACCESS ShareAccess;
  395. } Dcb;
  396. //
  397. // An File Control Block (Fcb)
  398. //
  399. struct {
  400. //
  401. // This is the maximum number of instances we can have for the
  402. // named pipe and the current number of instances is the open
  403. // count for the fcb (note that the current number also
  404. // correspondsto the number of Ccbs)
  405. //
  406. ULONG MaximumInstances;
  407. //
  408. // The assigned pipe configuration (FILE_PIPE_INBOUND,
  409. // FILE_PIPE_OUTBOUND, or FILE_PIPE_FULL_DUPLEX) and pipe
  410. // type (FILE_PIPE_MESSAGE_TYPE or
  411. // FILE_PIPE_BYTE_STREAM_TYPE).
  412. //
  413. NAMED_PIPE_CONFIGURATION NamedPipeConfiguration : 16;
  414. NAMED_PIPE_TYPE NamedPipeType : 16;
  415. //
  416. // The following field is the default timeout assigned to the
  417. // named pipe
  418. //
  419. LARGE_INTEGER DefaultTimeOut;
  420. //
  421. // The Following field is a queue head for a list of ccbs
  422. // that are opened under us
  423. //
  424. LIST_ENTRY CcbQueue;
  425. } Fcb;
  426. } Specific;
  427. //
  428. // The following field is the fully qualified file name for this FCB/DCB
  429. // starting from the root of the volume, and last file name in the
  430. // fully qualified name.
  431. //
  432. UNICODE_STRING FullFileName;
  433. UNICODE_STRING LastFileName;
  434. //
  435. // The following field contains a prefix table entry that is used when
  436. // searching a volume for a name (or longest matching prefix)
  437. //
  438. UNICODE_PREFIX_TABLE_ENTRY PrefixTableEntry;
  439. } FCB, DCB, ROOT_DCB;
  440. typedef FCB *PFCB;
  441. typedef DCB *PDCB;
  442. typedef ROOT_DCB *PROOT_DCB;
  443. typedef struct _CLIENT_INFO {
  444. PVOID ClientSession;
  445. USHORT ClientComputerNameLength;
  446. WCHAR ClientComputerBuffer[];
  447. } CLIENT_INFO, *PCLIENT_INFO;
  448. //
  449. // The Ccb record is allocated for every opened instance of a named pipe.
  450. // There are two parts to a ccb a paged part and a Nonpaged part. Both
  451. // parts are pointed at by the FsContext and FsContext2 field of a file
  452. // object.
  453. //
  454. typedef struct _CCB {
  455. //
  456. // Type of this record (must be NPFS_NTC_CCB).
  457. //
  458. NODE_TYPE_CODE NodeTypeCode;
  459. //
  460. // Pipe state indicates the current state of the pipe
  461. // (FILE_PIPE_DISCONNECTED_STATE, FILE_PIPE_LISTENING_STATE,
  462. // FILE_PIPE_CONNECTED_STATE, or FILE_PIPE_CLOSING_STATE).
  463. //
  464. UCHAR NamedPipeState;
  465. //
  466. // read mode (FILE_PIPE_MESSAGE_MODE or FILE_PIPE_BYTE_STREAM_MODE),
  467. // and completion mode (FILE_PIPE_QUEUE_OPERATION or
  468. // FILE_PIPE_COMPLETE_OPERATION) describe how to handle requests to the
  469. // pipe. Both of these fields are indexed by either FILE_PIPE_SERVER_END
  470. // or FILE_PIPE_CLIENT_END.
  471. //
  472. struct {
  473. UCHAR ReadMode : 1;
  474. UCHAR CompletionMode : 1;
  475. } ReadCompletionMode[2];
  476. //
  477. // Stored client impersonation level
  478. //
  479. SECURITY_QUALITY_OF_SERVICE SecurityQos;
  480. //
  481. // The following field is a list entry for the list of ccb that we
  482. // are a member of
  483. //
  484. LIST_ENTRY CcbLinks;
  485. //
  486. // A pointer to the paged Fcb, or Vcb that we are tied to
  487. //
  488. PFCB Fcb;
  489. //
  490. // Back pointers to the server and client file objects that have us
  491. // opened. This is indexed by either FILE_PIPE_CLIENT_END or
  492. // FILE_PIPE_SERVER_END.
  493. //
  494. PFILE_OBJECT FileObject[2];
  495. //
  496. // The following fields contain the session and process IDs of the
  497. // client side of the named pipe instance. They are originally set
  498. // to NULL (indicating local session) and the real client process
  499. // ID but can be changed via FsCtl calls.
  500. //
  501. PVOID ClientProcess;
  502. PCLIENT_INFO ClientInfo;
  503. //
  504. // A pointer to the Nonpaged part of the ccb
  505. //
  506. struct _NONPAGED_CCB *NonpagedCcb;
  507. //
  508. // The following data queues are used to contain the buffered information
  509. // for each direction in the pipe. They array is indexed by
  510. // PIPE_DIRECTION.
  511. //
  512. DATA_QUEUE DataQueue[2];
  513. //
  514. // Stored client security for impersonation
  515. //
  516. PSECURITY_CLIENT_CONTEXT SecurityClientContext;
  517. //
  518. // A queue of waiting listening IRPs. They are linked into the
  519. // Tail.Overlay.ListEntry field in the Irp.
  520. //
  521. LIST_ENTRY ListeningQueue;
  522. } CCB;
  523. typedef CCB *PCCB;
  524. typedef struct _NONPAGED_CCB {
  525. //
  526. // Type of this record (must be NPFS_NTC_NONPAGED_CCB)
  527. //
  528. NODE_TYPE_CODE NodeTypeCode;
  529. //
  530. // The following pointers denote the events we are to signal for the
  531. // server and client ends of the named pipe. The actual entry
  532. // is stored in the event table, and referenced here for easy access.
  533. // The client end is signaled if ever a read/write occurs to the client
  534. // of the pipe, and likewise for the server end. The array is
  535. // indexed by either FILE_PIPE_SERVER_END or FILE_PIPE_CLIENT_END.
  536. //
  537. PEVENT_TABLE_ENTRY EventTableEntry[2];
  538. //
  539. // Resource for synchronizing access
  540. //
  541. ERESOURCE Resource;
  542. } NONPAGED_CCB;
  543. typedef NONPAGED_CCB *PNONPAGED_CCB;
  544. //
  545. // The Root Dcb Ccb record is allocated for every opened instance of the
  546. // root dcb. This record is pointed at by FsContext2.
  547. //
  548. typedef struct _ROOT_DCB_CCB {
  549. //
  550. // Type of this record (must be NPFS_NTC_ROOT_DCB_CCB).
  551. //
  552. NODE_TYPE_CODE NodeTypeCode;
  553. //
  554. // The following field is a count of the last index returned
  555. // by query directory.
  556. //
  557. ULONG IndexOfLastCcbReturned;
  558. //
  559. // The following string is used as a query template for directory
  560. // query operations
  561. //
  562. PUNICODE_STRING QueryTemplate;
  563. } ROOT_DCB_CCB;
  564. typedef ROOT_DCB_CCB *PROOT_DCB_CCB;
  565. #endif // _NPSTRUC_