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.

746 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. // A pointer to the root DCB for this volume
  263. //
  264. struct _FCB *RootDcb;
  265. //
  266. // A count of the number of file objects that have opened the \NamedPipe
  267. // object directly, and also a count of the number of file objects
  268. // that have opened a name pipe or the root directory.
  269. //
  270. CLONG OpenCount;
  271. //
  272. // A prefix table that is used for quick, prefix directed, lookup of
  273. // FCBs/DCBs that are part of this volume
  274. //
  275. UNICODE_PREFIX_TABLE PrefixTable;
  276. //
  277. // A resource variable to control access to the volume specific data
  278. // structures
  279. //
  280. ERESOURCE Resource;
  281. //
  282. // The following table is used to hold the named pipe events
  283. //
  284. EVENT_TABLE EventTable;
  285. //
  286. // The following field is a queue of waiting IRPS of type WaitForNamedPipe
  287. //
  288. WAIT_QUEUE WaitQueue;
  289. } VCB;
  290. typedef VCB *PVCB;
  291. //
  292. // The Named Pipe Device Object is an I/O system device object with
  293. // additional workqueue parameters appended to the end. There is only
  294. // one of these records created for the entire system during system
  295. // initialization.
  296. //
  297. typedef struct _NPFS_DEVICE_OBJECT {
  298. DEVICE_OBJECT DeviceObject;
  299. //
  300. // This is the file system specific volume control block.
  301. //
  302. VCB Vcb;
  303. } NPFS_DEVICE_OBJECT;
  304. typedef NPFS_DEVICE_OBJECT *PNPFS_DEVICE_OBJECT;
  305. //
  306. // The Fcb/Dcb record corresponds to every opened named pipe and directory,
  307. // and to every directory on an opened path.
  308. //
  309. // The structure is really divided into two parts. FCB can be allocated
  310. // from paged pool which the NONPAGED_FCB must be allocated from non-paged
  311. // pool.
  312. //
  313. typedef struct _FCB {
  314. //
  315. // Type of this record (must be NPFS_NTC_FCB, or
  316. // NPFS_NTC_ROOT_DCB)
  317. //
  318. NODE_TYPE_CODE NodeTypeCode;
  319. //
  320. // The links for the queue of all fcbs for a specific dcb off of
  321. // Dcb.ParentDcbQueue. For the root directory this queue is empty
  322. //
  323. LIST_ENTRY ParentDcbLinks;
  324. //
  325. // A pointer to the Dcb that is the parent directory containing
  326. // this fcb. If this record itself is the root dcb then this field
  327. // is null.
  328. //
  329. struct _FCB *ParentDcb;
  330. //
  331. // A pointer to the Vcb containing this fcb
  332. //
  333. PVCB Vcb;
  334. //
  335. // A count of the number of file objects that have opened
  336. // this file/directory. For a pipe this is also the number of instances
  337. // created for the pipe.
  338. //
  339. CLONG OpenCount;
  340. //
  341. // A count of the number of server end file objects that have opened
  342. // this pipe. ServerOpenCount is incremented when OpenCount is
  343. // incremented (when the server end creates an instance), but is
  344. // decremented when the server end handle is closed, where OpenCount
  345. // isn't decremented until both side's handles are closed. When
  346. // ServerOpenCount is 0, a client's attempt to open a named pipe is
  347. // met with STATUS_OBJECT_NAME_NOT_FOUND, not STATUS_PIPE_NOT_AVAILABLE,
  348. // based on an assumption that since the server doesn't think it has
  349. // any instances open, the pipe really doesn't exist anymore. An
  350. // example of when this distinction is useful is when the server
  351. // process exits, but the client processes haven't closed their
  352. // handles yet.
  353. //
  354. CLONG ServerOpenCount;
  355. //
  356. // The following field points to the security descriptor for this named pipe
  357. //
  358. PSECURITY_DESCRIPTOR SecurityDescriptor;
  359. //
  360. // The following union is cased off of the node type code for the fcb.
  361. // There is a seperate case for the directory versus file fcbs.
  362. //
  363. union {
  364. //
  365. // A Directory Control Block (Dcb)
  366. //
  367. struct {
  368. //
  369. // A queue of the notify IRPs that will be completed when any
  370. // change is made to a file in the directory. Enqueued using
  371. // the Tail.Overlay.ListEntry of the Irp.
  372. //
  373. LIST_ENTRY NotifyFullQueue;
  374. //
  375. // A queue of the notify IRPs that will be completed only if a
  376. // file is added, deleted, or renamed in the directory. Enqueued
  377. // using the Tail.Overlay.ListEntry of the Irp.
  378. //
  379. LIST_ENTRY NotifyPartialQueue;
  380. //
  381. // A queue of all the fcbs/dcbs that are opened under this
  382. // Dcb.
  383. //
  384. LIST_ENTRY ParentDcbQueue;
  385. } Dcb;
  386. //
  387. // An File Control Block (Fcb)
  388. //
  389. struct {
  390. //
  391. // This is the maximum number of instances we can have for the
  392. // named pipe and the current number of instances is the open
  393. // count for the fcb (note that the current number also
  394. // correspondsto the number of Ccbs)
  395. //
  396. ULONG MaximumInstances;
  397. //
  398. // The assigned pipe configuration (FILE_PIPE_INBOUND,
  399. // FILE_PIPE_OUTBOUND, or FILE_PIPE_FULL_DUPLEX) and pipe
  400. // type (FILE_PIPE_MESSAGE_TYPE or
  401. // FILE_PIPE_BYTE_STREAM_TYPE).
  402. //
  403. NAMED_PIPE_CONFIGURATION NamedPipeConfiguration : 16;
  404. NAMED_PIPE_TYPE NamedPipeType : 16;
  405. //
  406. // The following field is the default timeout assigned to the
  407. // named pipe
  408. //
  409. LARGE_INTEGER DefaultTimeOut;
  410. //
  411. // The Following field is a queue head for a list of ccbs
  412. // that are opened under us
  413. //
  414. LIST_ENTRY CcbQueue;
  415. } Fcb;
  416. } Specific;
  417. //
  418. // The following field is the fully qualified file name for this FCB/DCB
  419. // starting from the root of the volume, and last file name in the
  420. // fully qualified name.
  421. //
  422. UNICODE_STRING FullFileName;
  423. UNICODE_STRING LastFileName;
  424. //
  425. // The following field contains a prefix table entry that is used when
  426. // searching a volume for a name (or longest matching prefix)
  427. //
  428. UNICODE_PREFIX_TABLE_ENTRY PrefixTableEntry;
  429. } FCB, DCB, ROOT_DCB;
  430. typedef FCB *PFCB;
  431. typedef DCB *PDCB;
  432. typedef ROOT_DCB *PROOT_DCB;
  433. typedef struct _CLIENT_INFO {
  434. PVOID ClientSession;
  435. USHORT ClientComputerNameLength;
  436. WCHAR ClientComputerBuffer[];
  437. } CLIENT_INFO, *PCLIENT_INFO;
  438. //
  439. // The Ccb record is allocated for every opened instance of a named pipe.
  440. // There are two parts to a ccb a paged part and a Nonpaged part. Both
  441. // parts are pointed at by the FsContext and FsContext2 field of a file
  442. // object.
  443. //
  444. typedef struct _CCB {
  445. //
  446. // Type of this record (must be NPFS_NTC_CCB).
  447. //
  448. NODE_TYPE_CODE NodeTypeCode;
  449. //
  450. // Pipe state indicates the current state of the pipe
  451. // (FILE_PIPE_DISCONNECTED_STATE, FILE_PIPE_LISTENING_STATE,
  452. // FILE_PIPE_CONNECTED_STATE, or FILE_PIPE_CLOSING_STATE).
  453. //
  454. UCHAR NamedPipeState;
  455. //
  456. // read mode (FILE_PIPE_MESSAGE_MODE or FILE_PIPE_BYTE_STREAM_MODE),
  457. // and completion mode (FILE_PIPE_QUEUE_OPERATION or
  458. // FILE_PIPE_COMPLETE_OPERATION) describe how to handle requests to the
  459. // pipe. Both of these fields are indexed by either FILE_PIPE_SERVER_END
  460. // or FILE_PIPE_CLIENT_END.
  461. //
  462. struct {
  463. UCHAR ReadMode : 1;
  464. UCHAR CompletionMode : 1;
  465. } ReadCompletionMode[2];
  466. //
  467. // Stored client impersonation level
  468. //
  469. SECURITY_QUALITY_OF_SERVICE SecurityQos;
  470. //
  471. // The following field is a list entry for the list of ccb that we
  472. // are a member of
  473. //
  474. LIST_ENTRY CcbLinks;
  475. //
  476. // A pointer to the paged Fcb, or Vcb that we are tied to
  477. //
  478. PFCB Fcb;
  479. //
  480. // Back pointers to the server and client file objects that have us
  481. // opened. This is indexed by either FILE_PIPE_CLIENT_END or
  482. // FILE_PIPE_SERVER_END.
  483. //
  484. PFILE_OBJECT FileObject[2];
  485. //
  486. // The following fields contain the session and process IDs of the
  487. // client side of the named pipe instance. They are originally set
  488. // to NULL (indicating local session) and the real client process
  489. // ID but can be changed via FsCtl calls.
  490. //
  491. PVOID ClientProcess;
  492. PCLIENT_INFO ClientInfo;
  493. //
  494. // A pointer to the Nonpaged part of the ccb
  495. //
  496. struct _NONPAGED_CCB *NonpagedCcb;
  497. //
  498. // The following data queues are used to contain the buffered information
  499. // for each direction in the pipe. They array is indexed by
  500. // PIPE_DIRECTION.
  501. //
  502. DATA_QUEUE DataQueue[2];
  503. //
  504. // Stored client security for impersonation
  505. //
  506. PSECURITY_CLIENT_CONTEXT SecurityClientContext;
  507. //
  508. // A queue of waiting listening IRPs. They are linked into the
  509. // Tail.Overlay.ListEntry field in the Irp.
  510. //
  511. LIST_ENTRY ListeningQueue;
  512. } CCB;
  513. typedef CCB *PCCB;
  514. typedef struct _NONPAGED_CCB {
  515. //
  516. // Type of this record (must be NPFS_NTC_NONPAGED_CCB)
  517. //
  518. NODE_TYPE_CODE NodeTypeCode;
  519. //
  520. // The following pointers denote the events we are to signal for the
  521. // server and client ends of the named pipe. The actual entry
  522. // is stored in the event table, and referenced here for easy access.
  523. // The client end is signaled if ever a read/write occurs to the client
  524. // of the pipe, and likewise for the server end. The array is
  525. // indexed by either FILE_PIPE_SERVER_END or FILE_PIPE_CLIENT_END.
  526. //
  527. PEVENT_TABLE_ENTRY EventTableEntry[2];
  528. //
  529. // Resource for synchronizing access
  530. //
  531. ERESOURCE Resource;
  532. } NONPAGED_CCB;
  533. typedef NONPAGED_CCB *PNONPAGED_CCB;
  534. //
  535. // The Root Dcb Ccb record is allocated for every opened instance of the
  536. // root dcb. This record is pointed at by FsContext2.
  537. //
  538. typedef struct _ROOT_DCB_CCB {
  539. //
  540. // Type of this record (must be NPFS_NTC_ROOT_DCB_CCB).
  541. //
  542. NODE_TYPE_CODE NodeTypeCode;
  543. //
  544. // The following field is a count of the last index returned
  545. // by query directory.
  546. //
  547. ULONG IndexOfLastCcbReturned;
  548. //
  549. // The following string is used as a query template for directory
  550. // query operations
  551. //
  552. PUNICODE_STRING QueryTemplate;
  553. } ROOT_DCB_CCB;
  554. typedef ROOT_DCB_CCB *PROOT_DCB_CCB;
  555. #endif // _NPSTRUC_