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.

841 lines
27 KiB

  1. /*
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. volume.h
  5. Abstract:
  6. This module contains volume related data structures.
  7. Author:
  8. Jameel Hyder (microsoft!jameelh)
  9. Revision History:
  10. 25 Apr 1992 Initial Version
  11. Notes: Tab stop: 4
  12. --*/
  13. #ifndef _VOLUME_
  14. #define _VOLUME_
  15. #define IDINDEX_BUCKETS_DIR_MIN 16
  16. #define IDINDEX_BUCKETS_FILE_MIN 32
  17. #define IDINDEX_BUCKETS_DIR_INIT 64 // no index info? assume ~1000 dirs
  18. #define IDINDEX_BUCKETS_FILE_INIT 1024 // no index info? assume ~20000 files
  19. #define IDINDEX_BUCKETS_32K 32768
  20. #define IDINDEX_BUCKETS_MAX 65536
  21. #define IDINDEX_CACHE_ENTRIES 512
  22. #define APPL_BUCKETS 16
  23. #define ICON_BUCKETS 16
  24. #define AFP_VOLUME_FIXED_DIR 2 // Volume Signature
  25. // These flags should be consistent with AFP
  26. // The UI (registry) visible definitions are in macfile.h
  27. // #define AFP_VOLUME_READONLY 0x00000001
  28. // #define VOLUME_GUESTACCESS 0x00008000
  29. // #define VOLUME_EXCLUSIVE 0x00010000
  30. // #define AFP_VOLUME_HAS_CUSTOM_ICON 0x00020000
  31. // #define AFP_VOLUME_4GB 0x00040000
  32. // #define AFP_VOLUME_AGE_DFES 0x00080000
  33. #define AFP_VOLUME_HASPASSWORD 0x00000002
  34. #define AFP_VOLUME_SUPPORTS_FILEID 0x00000004
  35. #define AFP_VOLUME_SUPPORTS_CATSRCH 0x00000008
  36. #define AFP_VOLUME_SUPPORTS_BLANKPRV 0x00000010
  37. #define AFP_VOLUME_MASK_AFP 0x0000001F // This is all AFP can see
  38. #define VOLUME_PROCESSING_NOTIFY 0x00000020 // Notify processing under way
  39. #define VOLUME_NOTIFY_POSTED 0x00000040 // Notify has been posted
  40. #define VOLUME_STOPPED 0x00000080 // The volume is about to stop
  41. // Set when server is stopping
  42. #define VOLUME_DELETED 0x00000100 // This volume is about to be
  43. // deleted, set when volume is
  44. // deleted by admin
  45. #define VOLUME_IDDBHDR_DIRTY 0x00000200 // The header needs to be written ASAP
  46. #define VOLUME_NTFS 0x00000400 // Volume is an NTFS volume
  47. #define VOLUME_INTRANSITION 0x00000800 // VolumeAdd is in progress
  48. // Is not usable still.
  49. #define VOLUME_SCAVENGER_RUNNING 0x00001000 // Volume is referenced for scavenger
  50. #define VOLUME_CDFS_INVALID 0x00002000 // If this is set, then no go
  51. #define VOLUME_INITIAL_CACHE 0x00004000 // Set initially when caching
  52. #define VOLUME_CD_HFS 0x00200000 // volume is a CD with HFS support
  53. #define VOLUME_DISKQUOTA_ENABLED 0x00400000 // diskquota is enabled on this volume
  54. #define VOLUME_NEW_FIRST_PASS 0x00800000 // first pass of id db building
  55. #define VOLUME_SRVR_NOTIF_PENDING 0x01000000 // server notification is pending
  56. // Values for scavenger routines
  57. #define VOLUME_NTFS_SCAVENGER_INTERVAL 60 // # of seconds
  58. #define VOLUME_CDFS_SCAVENGER_INTERVAL 60 // # of seconds
  59. //#define VOLUME_IDDB_UPDATE_INTERVAL 600 // # of seconds
  60. //#define MAX_INVOCATIONS_TO_SKIP 60 // # of passes
  61. //#define MAX_CHANGES_BEFORE_WRITE 1000 // # of changes
  62. #define VOLUME_OURCHANGE_AGE 30 // # of seconds
  63. #define OURCHANGE_AGE 10 // # of seconds
  64. //
  65. // The ChangeNotify delay is introduced to prevent the problem where
  66. // the PC side is doing a copyfile or forkize of a macfile, and as
  67. // soon as we receive the notification of the initial create we will
  68. // slap on our AFPInfo stream. Then when the CopyFile or forkize operation
  69. // gets around to writing its AFPInfo, we do not get notified and will not
  70. // reread the information. In this case, a mac file copied from one volume
  71. // to another (e.g.) will not show up with the correct finder info.
  72. //
  73. #define VOLUME_NTFY_DELAY 3 // # of seconds
  74. #define VOLUME_IDDB_AGE_DELAY 60*60 // # of seconds
  75. #define VOLUME_IDDB_AGE_GRANULARITY 30 // # of invocations
  76. #define VOLUME_STARTUP_WAIT 5 // # of seconds to wait
  77. // make sure there is enough room to hold a change notification for a
  78. // rename operation on a maximum length win32 path (which is 260 chars)
  79. #define AFP_VOLUME_NOTIFY_STARTING_BUFSIZE (2048 - POOL_OVERHEAD)
  80. #define AFP_VOLUME_NOTIFY_MAX_BUFSIZE 8*16384
  81. // List of these structures hangs off the volume descriptor to list the
  82. // changes initiated by us that should be filtered from the ChangeNotify
  83. // list of changes.
  84. typedef struct _OurChange
  85. {
  86. LIST_ENTRY oc_Link;
  87. UNICODE_STRING oc_Path;
  88. AFPTIME oc_Time; // Time when this was queued.
  89. } OUR_CHANGE, *POUR_CHANGE;
  90. // defines for indices into vds_OurChangeList
  91. #define AFP_CHANGE_ACTION_ADDED 0
  92. #define AFP_CHANGE_ACTION_REMOVED 1
  93. #define AFP_CHANGE_ACTION_MODIFIED 2
  94. #define AFP_CHANGE_ACTION_RENAMED 3
  95. #define AFP_CHANGE_ACTION_MODIFIED_STREAM 4
  96. #define AFP_CHANGE_ACTION_MAX AFP_CHANGE_ACTION_MODIFIED_STREAM
  97. #define NUM_AFP_CHANGE_ACTION_LISTS (AFP_CHANGE_ACTION_MAX + 1)
  98. // Convert an NT FILE_ACTION_xxx (ntioapi.h) to an array index into
  99. // vds_OurChangeList array. Note the close tie between the first 4
  100. // AFP_CHANGE_ACTION_xxx and the values of FILE_ACTION_xxx in ntioapi.h
  101. #define AFP_CHANGE_ACTION(NTAction) \
  102. (NTAction == FILE_ACTION_MODIFIED_STREAM ? AFP_CHANGE_ACTION_MODIFIED_STREAM : (NTAction - 1))
  103. /*
  104. * All changes to the volume descriptor should be protected by vds_VolLock
  105. * Changes to the Id Db and the desktop Db should be protected by their
  106. * respective locks.
  107. *
  108. * NOTE: The volume path and name (unicode) must be uppercased, since when
  109. * looking up or adding a volume, we will be holding a spinlock, and
  110. * case insensitive string compares cannot be done at DPC level since
  111. * the codepages are kept in paged memory, and we can't take a page
  112. * fault at DPC level.
  113. */
  114. #if DBG
  115. #define VOLDESC_SIGNATURE *(DWORD *)"VDS"
  116. #define VALID_VOLDESC(pVolDesc) (((pVolDesc) != NULL) && \
  117. ((pVolDesc)->Signature == VOLDESC_SIGNATURE))
  118. #else
  119. #define VALID_VOLDESC(pVolDesc) ((pVolDesc) != NULL)
  120. #endif
  121. typedef struct _VolDesc
  122. {
  123. #if DBG
  124. DWORD Signature;
  125. DWORD QuadAlign1;
  126. #endif
  127. struct _VolDesc * vds_Next; // Pointer to next volume
  128. DWORD vds_UseCount; // Number of active connections
  129. DWORD vds_RefCount; // Number of references.
  130. // Cannot be freed till both of the
  131. // above go to ZERO. Of course there
  132. // is a RefCount for every UseCount
  133. // Configuration information.
  134. DWORD vds_Flags; // Volume flags
  135. LONG vds_VolId; // Volume Id for FPOpenVol
  136. DWORD vds_MaxUses; // Maximum opens on a volume
  137. UNICODE_STRING vds_Name; // Volume name in unicode
  138. UNICODE_STRING vds_UpCaseName; // Volume name in UPPER CASE unicode
  139. ANSI_STRING vds_MacName; // Volume name in Mac Ansi
  140. ANSI_STRING vds_MacPassword; // Volume password in Mac Ansi
  141. UNICODE_STRING vds_Path; // File system path to the volume root;
  142. // Path is always upper cased
  143. LARGE_INTEGER vds_VolumeSize; // Size of volume
  144. LARGE_INTEGER vds_FreeBytes; // Free space on the volume
  145. #define vds_pFileObject vds_hRootDir.fsh_FileObject
  146. FILESYSHANDLE vds_hRootDir; // Handle to open root directory
  147. // in the servers context. All
  148. // subsequent opens are relative
  149. // to this handle
  150. FILESYSHANDLE vds_hNWT; // Handle to Network Trash so it can't
  151. // be deleted from under us (NTFS)
  152. DWORD vds_AllocationBlockSize;
  153. // Bytes per sector
  154. // The following fields are used by the Id database code and are copied
  155. // to/from the on-disk idDb header. Protected by vds_VolLock.
  156. DWORD vds_LastId; // Highest id that is assigned
  157. AFPTIME vds_CreateTime; // Creation time for this volume
  158. AFPTIME vds_ModifiedTime; // Modified time for this volume
  159. AFPTIME vds_BackupTime; // Backup time for this volume
  160. #ifdef AGE_DFES
  161. DWORD vds_ScavengerInvocationCnt;
  162. // Used by the volume scavenger to fire off
  163. // AfpAgeDfEntries
  164. #endif
  165. DWORD vds_RequiredNotifyBufLen;
  166. // How deep is the tree. This is used by
  167. // the afpVolumePostnotify to allocate an
  168. // appropriate buffer.
  169. #ifdef BLOCK_MACS_DURING_NOTIFYPROC
  170. DWORD vds_QueuedNotifyCount;
  171. // How many change notify buffers
  172. // have moved into the global queue
  173. // for this volume -- This value is
  174. // ONLY touched by the Change
  175. // Notify thread.
  176. #endif
  177. SWMR vds_IdDbAccessLock; // Access cookie for the id db
  178. // Protects the vds_pDfexxxBuckets.
  179. LONG vds_cScvgrIdDb; // # of times the update to the Id
  180. // database was passed up
  181. DWORD vds_NumDirDfEntries;// Number of directory DfEntries in this volume
  182. DWORD vds_NumFileDfEntries;// Number of file DfEntries in this volume
  183. struct _DirFileEntry * vds_pDfeRoot; // Pointer to DFE of root
  184. DWORD vds_DirHashTableSize;
  185. DWORD vds_FileHashTableSize;
  186. struct _DirFileEntry ** vds_pDfeDirBucketStart;
  187. struct _DirFileEntry ** vds_pDfeFileBucketStart;
  188. // IdDb DfEntry hash buckets
  189. struct _DirFileEntry * vds_pDfeCache[IDINDEX_CACHE_ENTRIES];
  190. // IdDb DfEntry cache
  191. // The following fields are used by the desktop database code
  192. LONG vds_cScvgrDt; // # of times the update to the desktop
  193. // database was passed up
  194. SWMR vds_DtAccessLock; // Access cookie for the desktop db
  195. // Protects the following FIVE fields
  196. // The following fields are copied to/from the on-disk Desktop header.
  197. // Protected by vds_VolLock.
  198. LONG vds_cApplEnts; // Number of APPL entries
  199. LONG vds_cIconEnts; // Number of ICON entries
  200. struct _ApplInfo2 * vds_pApplBuckets[APPL_BUCKETS];
  201. // APPL hash buckets
  202. struct _IconInfo * vds_pIconBuckets[ICON_BUCKETS];
  203. // ICON hash buckets
  204. SWMR vds_ExchangeFilesLock; // Access to the FileId stored
  205. // in an OpenForkDesc, used by
  206. // FpExchangeFiles and fork APIs
  207. LIST_ENTRY vds_OurChangeList[NUM_AFP_CHANGE_ACTION_LISTS];
  208. // ^^^
  209. // Lists of create/delete/move/rename
  210. // operations initiated by this server
  211. LIST_ENTRY vds_ChangeNotifyLookAhead;
  212. // ^^^
  213. // List of all completed (but not yet
  214. // processed) DELETE or RENAME changes
  215. // on this Volume.
  216. LIST_ENTRY vds_DelayedNotifyList;
  217. struct _OpenForkDesc * vds_pOpenForkDesc;
  218. // List of open forks for this volume
  219. LONG vds_cPrivateNotifies;
  220. // Count of private notifies
  221. LONG vds_maxPrivateNotifies;
  222. // Keep track of max private notifies
  223. PBYTE vds_EnumBuffer; // Used during notify processing to cache in the tree
  224. LONG vds_cOutstandingNotifies;
  225. // Used in conjunction with above
  226. PIRP vds_pIrp; // Irp used by Notify, we never
  227. // free this until its time to
  228. // delete or stop
  229. DWORD vds_TimeMustSendNotify; // time at which we *must* send the notif
  230. DWORD vds_TimeToSendNotify; // when to send the next notification
  231. AFP_SPIN_LOCK vds_VolLock; // Lock for this volume
  232. BOOLEAN MacLimitExceeded; // True if # folders or volume size exceeds Apple limits
  233. LARGE_INTEGER vds_IndxStTime;
  234. } VOLDESC, *PVOLDESC;
  235. // AppleShare limit for files+folders in a volume: 65535
  236. #define APLIMIT_MAX_FOLDERS 0xffff
  237. #define IS_VOLUME_NTFS(pVolDesc) (((pVolDesc)->vds_Flags & VOLUME_NTFS) ? True : False)
  238. #define IS_VOLUME_RO(pVolDesc) (((pVolDesc)->vds_Flags & AFP_VOLUME_READONLY) ? True : False)
  239. #define IS_VOLUME_CD_HFS(pVolDesc) (((pVolDesc)->vds_Flags & VOLUME_CD_HFS) ? True : False)
  240. #define EXCLUSIVE_VOLUME(pVolDesc) (((pVolDesc)->vds_Flags & AFP_VOLUME_EXCLUSIVE) ? True : False)
  241. #define IS_VOLUME_AGING_DFES(pVolDesc) (((pVolDesc)->vds_Flags & AFP_VOLUME_AGE_DFES) ? True : False)
  242. #define CONN_DESKTOP_CLOSED 0x0000
  243. #define CONN_DESKTOP_OPENED 0x0001
  244. #define CONN_CLOSING 0x8000
  245. #if DBG
  246. #define CONNDESC_SIGNATURE *(DWORD *)"CDS"
  247. #define VALID_CONNDESC(pConnDesc) \
  248. (((pConnDesc) != NULL) && \
  249. ((pConnDesc)->Signature == CONNDESC_SIGNATURE))
  250. #else
  251. #define VALID_CONNDESC(pConnDesc) ((pConnDesc) != NULL)
  252. #endif
  253. typedef struct _ConnDesc
  254. {
  255. #if DBG
  256. DWORD Signature;
  257. #endif
  258. LONG cds_RefCount; // Number of references to the open volume
  259. DWORD cds_Flags; // One or more of the bits defined above
  260. struct _ConnDesc * cds_Next; // Link to next open volume for this
  261. // session. Starts from the SDA
  262. struct _ConnDesc * cds_NextGlobal; // Link to next for global list.
  263. // Starts from AfpConnList
  264. struct _VolDesc * cds_pVolDesc; // Pointer to volume structure
  265. PSDA cds_pSda; // Session that opened this volume
  266. LARGE_INTEGER cds_QuotaLimit; // how much is the DiskQuota limit
  267. LARGE_INTEGER cds_QuotaAvl; // how much DiskQuota is available
  268. DWORD cds_ConnId; // Connection Id assigned by the server
  269. AFPTIME cds_TimeOpened; // Time stamp when volume opened
  270. // in macintosh time
  271. LONG cds_cOpenForks; // Number of open forks from this conn
  272. PENUMDIR cds_pEnumDir; // Current enumerated directory
  273. AFP_SPIN_LOCK cds_ConnLock; // Lock for this connection
  274. } CONNDESC, *PCONNDESC;
  275. #define IS_CONN_NTFS(pConnDesc) IS_VOLUME_NTFS((pConnDesc)->cds_pVolDesc)
  276. #define IS_CONN_CD_HFS(pConnDesc) IS_VOLUME_CD_HFS((pConnDesc)->cds_pVolDesc)
  277. // Volume parameters bitmap definitions
  278. #define VOL_BITMAP_ATTR 0x0001
  279. #define VOL_BITMAP_SIGNATURE 0x0002
  280. #define VOL_BITMAP_CREATETIME 0x0004
  281. #define VOL_BITMAP_MODIFIEDTIME 0x0008
  282. #define VOL_BITMAP_BACKUPTIME 0x0010
  283. #define VOL_BITMAP_VOLUMEID 0x0020
  284. #define VOL_BITMAP_BYTESFREE 0x0040
  285. #define VOL_BITMAP_VOLUMESIZE 0x0080
  286. #define VOL_BITMAP_VOLUMENAME 0x0100
  287. #define VOL_BITMAP_EXTBYTESFREE 0x0200
  288. #define VOL_BITMAP_EXTBYTESTOTAL 0x0400
  289. #define VOL_BITMAP_ALLOCBLKSIZE 0x0800
  290. #define VOL_BITMAP_MASK 0x0FFF
  291. typedef VOID (FASTCALL *NOTIFYPROCESSOR)(IN PVOID);
  292. // Structure of a notify buffer. The Mdl describes only the Buffer following the struct.
  293. typedef struct _VolumeNotify
  294. {
  295. #define Notify_NextFree Notify_NextOverflow
  296. struct _VolumeNotify * Notify_NextOverflow; // Overflow links
  297. LIST_ENTRY vn_List; // Chained from AfpVolumeNotifyQueue[i]
  298. union
  299. {
  300. LIST_ENTRY vn_DelRenLink; // Chained from vds_ChangeNotifyLookAhead
  301. // - VALID ONLY IFF THE ACTION HAS THE PRIVATE BIT CLEAR
  302. struct
  303. {
  304. DWORD vn_ParentId; // Afp Id of the parent
  305. // - VALID ONLY IFF THE ACTION HAS THE PRIVATE BIT SET
  306. DWORD vn_TailLength; // Length in bytes of the last component of the path
  307. // - VALID ONLY IFF THE ACTION HAS THE PRIVATE BIT SET
  308. };
  309. };
  310. NOTIFYPROCESSOR vn_Processor; // Routine that processes the notification
  311. AFPTIME vn_TimeStamp; // When the notify came in
  312. PVOLDESC vn_pVolDesc; // Volume being watched
  313. DWORD vn_StreamId; // Stream Id
  314. LONG vn_VariableLength;
  315. // followed by FILE_NOTIFY_INFORMATION
  316. } VOL_NOTIFY, *PVOL_NOTIFY;
  317. // Notify's come in four sizes. This helps in efficiently managing them in a block
  318. // package (see later). THESE SIZES NEED TO BE 4*N, else we run into alignment
  319. // faults on architectures that require it.
  320. #define NOTIFY_INDEX_TINY 0
  321. #define NOTIFY_INDEX_SMALL 1
  322. #define NOTIFY_INDEX_MEDIUM 2
  323. #define NOTIFY_INDEX_LARGE 3
  324. //
  325. // Make sure each of the sizes below (XXX_U) are multiple of 8
  326. //
  327. #define NOTIFY_SIZE_TINY 128 // These are lengths for ANSI names
  328. #define NOTIFY_SIZE_SMALL 256 // - ditto -
  329. #define NOTIFY_SIZE_MEDIUM 512 // - ditto -
  330. #define NOTIFY_SIZE_LARGE 1024 // - ditto - corres. to AFP_FILENAME_LEN
  331. #define NOTIFY_SIZE_TINY_U NOTIFY_SIZE_TINY*sizeof(WCHAR) // These are lengths for UNICODE names
  332. #define NOTIFY_SIZE_SMALL_U NOTIFY_SIZE_SMALL*sizeof(WCHAR) // - ditto -
  333. #define NOTIFY_SIZE_MEDIUM_U NOTIFY_SIZE_MEDIUM*sizeof(WCHAR) // - ditto -
  334. #define NOTIFY_SIZE_LARGE_U NOTIFY_SIZE_LARGE*sizeof(WCHAR) // - ditto - corres. to AFP_FILENAME_LEN
  335. #define NOTIFY_USIZE_TO_INDEX(_Size) \
  336. (((_Size) <= NOTIFY_SIZE_TINY_U) ? NOTIFY_INDEX_TINY : \
  337. (((_Size) <= NOTIFY_SIZE_SMALL_U) ? NOTIFY_INDEX_SMALL : \
  338. (((_Size) <= NOTIFY_SIZE_MEDIUM_U) ? NOTIFY_INDEX_MEDIUM : NOTIFY_INDEX_LARGE)))
  339. // Notify Blocks are aged after NOTIFY_MAX_BLOCK_AGE*NOTIFY_DIR_BLOCK_AGE_TIME seconds (currently 1 min/s)
  340. #define NOTIFY_MAX_BLOCK_AGE 1
  341. #define NOTIFY_DIR_BLOCK_AGE_TIME 60 // # of seconds
  342. #define NOTIFY_MAX_BLOCK_TYPE 4 // For TINY, SMALL, MEDIUM & LARGE
  343. #define VALID_NOTIFY_BLOCK(pDfeBlock) ((pDfeBlock) != NULL)
  344. typedef struct _Notify_Block
  345. {
  346. struct _Notify_Block * dfb_Next; // Link to next
  347. struct _Notify_Block ** dfb_Prev; // Link to previous
  348. USHORT dfb_NumFree; // # of free DFEs in this block
  349. BYTE dfb_Age; // Age of the Block if all are free
  350. BOOLEAN dfb_fDir; // TRUE if it is a Dir DFB - else a file DFB
  351. PVOL_NOTIFY dfb_FreeHead; // Head of the list of free DFEs
  352. } VOL_NOTIFY_BLOCK, *PVOL_NOTIFY_BLOCK, **PPVOL_NOTIFY_BLOCK;
  353. GLOBAL PVOL_NOTIFY_BLOCK afpDirNotifyFreeBlockHead[NOTIFY_MAX_BLOCK_TYPE] EQU { NULL, NULL, NULL };
  354. GLOBAL PVOL_NOTIFY_BLOCK afpDirNotifyPartialBlockHead[NOTIFY_MAX_BLOCK_TYPE] EQU { NULL, NULL, NULL };
  355. GLOBAL PVOL_NOTIFY_BLOCK afpDirNotifyUsedBlockHead[NOTIFY_MAX_BLOCK_TYPE] EQU { NULL, NULL, NULL };
  356. GLOBAL SHORT afpNotifyUnicodeBufSize[NOTIFY_MAX_BLOCK_TYPE] EQU \
  357. { \
  358. NOTIFY_SIZE_TINY_U, NOTIFY_SIZE_SMALL_U, \
  359. NOTIFY_SIZE_MEDIUM_U, NOTIFY_SIZE_LARGE_U \
  360. };
  361. GLOBAL USHORT afpNotifyDirBlockSize[NOTIFY_MAX_BLOCK_TYPE] EQU \
  362. { \
  363. (USHORT)(sizeof(VOL_NOTIFY) + sizeof(FILE_NOTIFY_INFORMATION) + (AFP_LONGNAME_LEN+1)*sizeof(WCHAR) + NOTIFY_SIZE_TINY_U), \
  364. (USHORT)(sizeof(VOL_NOTIFY) + sizeof(FILE_NOTIFY_INFORMATION) + (AFP_LONGNAME_LEN+1)*sizeof(WCHAR) + NOTIFY_SIZE_SMALL_U), \
  365. (USHORT)(sizeof(VOL_NOTIFY) + sizeof(FILE_NOTIFY_INFORMATION) + (AFP_LONGNAME_LEN+1)*sizeof(WCHAR) + NOTIFY_SIZE_MEDIUM_U), \
  366. (USHORT)(sizeof(VOL_NOTIFY) + sizeof(FILE_NOTIFY_INFORMATION) + (AFP_LONGNAME_LEN+1)*sizeof(WCHAR) + NOTIFY_SIZE_LARGE_U) \
  367. };
  368. GLOBAL USHORT afpNotifyNumDirBlocks[NOTIFY_MAX_BLOCK_TYPE] EQU \
  369. { \
  370. (PAGE_SIZE - sizeof(VOL_NOTIFY_BLOCK))/ \
  371. (sizeof(VOL_NOTIFY) + sizeof(FILE_NOTIFY_INFORMATION) + (AFP_LONGNAME_LEN+1)*sizeof(WCHAR) + NOTIFY_SIZE_TINY_U), \
  372. (PAGE_SIZE - sizeof(VOL_NOTIFY_BLOCK))/ \
  373. (sizeof(VOL_NOTIFY) + sizeof(FILE_NOTIFY_INFORMATION) + (AFP_LONGNAME_LEN+1)*sizeof(WCHAR) + NOTIFY_SIZE_SMALL_U),\
  374. (PAGE_SIZE - sizeof(VOL_NOTIFY_BLOCK))/ \
  375. (sizeof(VOL_NOTIFY) + sizeof(FILE_NOTIFY_INFORMATION) + (AFP_LONGNAME_LEN+1)*sizeof(WCHAR) + NOTIFY_SIZE_MEDIUM_U),\
  376. (PAGE_SIZE - sizeof(VOL_NOTIFY_BLOCK))/ \
  377. (sizeof(VOL_NOTIFY) + sizeof(FILE_NOTIFY_INFORMATION) + (AFP_LONGNAME_LEN+1)*sizeof(WCHAR) + NOTIFY_SIZE_LARGE_U) \
  378. };
  379. GLOBAL SWMR afpNotifyBlockLock EQU { 0 };
  380. GLOBAL LONG afpNotifyAllocCount EQU 0;
  381. GLOBAL LONG afpNotifyBlockAllocCount EQU 0;
  382. GLOBAL LONG afpMaxNotifyBlockAllocCount EQU 0;
  383. GLOBAL LONG afpNotify64kBlockCount EQU 0;
  384. // For maintaining track of delayed transactions
  385. typedef struct _DELAYED_NOTIFY {
  386. LIST_ENTRY dn_List;
  387. UNICODE_STRING filename;
  388. } DELAYED_NOTIFY, *PDELAYED_NOTIFY;
  389. // largest volume id that's currently in use.
  390. GLOBAL LONG afpLargestVolIdInUse EQU 0;
  391. GLOBAL LONG AfpVolCount EQU 0; // Total number of volumes
  392. GLOBAL PVOLDESC AfpVolumeList EQU NULL; // List of volumes
  393. GLOBAL AFP_SPIN_LOCK AfpVolumeListLock EQU {0}; // Lock for AfpVolumeList,
  394. GLOBAL SWMR AfpVolumeListSwmr; // Access cookie VolumeNotifyList
  395. // AfpVolCount,
  396. // AfpVolumeNotifyList,
  397. // AfpVolumeNotifyCount
  398. GLOBAL PCONNDESC AfpConnList EQU NULL; // Global connection list
  399. GLOBAL AFP_SPIN_LOCK AfpConnLock EQU { 0 }; // Lock for AfpConnList
  400. GLOBAL UNICODE_STRING AfpNetworkTrashNameU EQU { 0 };
  401. GLOBAL KQUEUE AfpVolumeNotifyQueue[NUM_NOTIFY_QUEUES] EQU { 0 };
  402. GLOBAL LIST_ENTRY AfpVolumeNotifyList[NUM_NOTIFY_QUEUES] EQU { 0 };
  403. GLOBAL LIST_ENTRY AfpVirtualMemVolumeNotifyList[NUM_NOTIFY_QUEUES] EQU { 0 };
  404. // Count of change notification buffers that are in the list
  405. GLOBAL LONG AfpNotifyListCount[NUM_NOTIFY_QUEUES] EQU { 0 };
  406. // Count of change notification buffers that have transitioned into the queue.
  407. GLOBAL LONG AfpNotifyQueueCount[NUM_NOTIFY_QUEUES] EQU { 0 };
  408. GLOBAL VOL_NOTIFY AfpTerminateNotifyThread EQU { 0 };
  409. GLOBAL LONG ChangeNotifyQueueLimit EQU 200000;
  410. #define AfpVolumeQueueChangeNotify(pVolNotify, pNotifyQueue) \
  411. { \
  412. KeInsertQueue(pNotifyQueue, \
  413. &(pVolNotify)->vn_List); \
  414. }
  415. // Used for PRIVATE notifies of directory ADDED
  416. #define AFP_QUEUE_NOTIFY_IMMEDIATELY BEGINNING_OF_TIME
  417. #define AfpVolumeInsertChangeNotifyList(pVolNotify, pVolDesc) \
  418. { \
  419. PLIST_ENTRY pListHead; \
  420. \
  421. pListHead = &AfpVolumeNotifyList[(pVolDesc)->vds_VolId % NUM_NOTIFY_QUEUES]; \
  422. if (pVolNotify->vn_TimeStamp != AFP_QUEUE_NOTIFY_IMMEDIATELY) \
  423. { \
  424. ExInterlockedInsertTailList(pListHead, \
  425. &(pVolNotify)->vn_List, \
  426. &(AfpVolumeListLock.SpinLock)); \
  427. } \
  428. else \
  429. { \
  430. ExInterlockedInsertHeadList(pListHead, \
  431. &(pVolNotify)->vn_List, \
  432. &(AfpVolumeListLock.SpinLock)); \
  433. } \
  434. INTERLOCKED_ADD_ULONG(&AfpNotifyListCount[(pVolDesc)->vds_VolId % NUM_NOTIFY_QUEUES], \
  435. 1, \
  436. &AfpVolumeListLock); \
  437. }
  438. #define AfpIdDbHdrToVolDesc(_pIdDbHdr, _pVolDesc) \
  439. { \
  440. (_pVolDesc)->vds_LastId = (_pIdDbHdr)->idh_LastId; \
  441. (_pVolDesc)->vds_CreateTime = (_pIdDbHdr)->idh_CreateTime; \
  442. (_pVolDesc)->vds_ModifiedTime = (_pIdDbHdr)->idh_ModifiedTime; \
  443. (_pVolDesc)->vds_BackupTime = (_pIdDbHdr)->idh_BackupTime; \
  444. }
  445. #define AfpVolDescToIdDbHdr(_pVolDesc, _pIdDbHdr) \
  446. { \
  447. (_pIdDbHdr)->idh_Signature = AFP_SERVER_SIGNATURE; \
  448. (_pIdDbHdr)->idh_Version = AFP_IDDBHDR_VERSION; \
  449. (_pIdDbHdr)->idh_LastId = (_pVolDesc)->vds_LastId; \
  450. (_pIdDbHdr)->idh_CreateTime = (_pVolDesc)->vds_CreateTime; \
  451. (_pIdDbHdr)->idh_ModifiedTime = (_pVolDesc)->vds_ModifiedTime; \
  452. (_pIdDbHdr)->idh_BackupTime = (_pVolDesc)->vds_BackupTime; \
  453. }
  454. #define AfpDtHdrToVolDesc(_pDtHdr, _pVolDesc) \
  455. { \
  456. (_pVolDesc)->vds_cApplEnts = (_pDtHdr)->dtp_cApplEnts; \
  457. (_pVolDesc)->vds_cIconEnts = (_pDtHdr)->dtp_cIconEnts; \
  458. }
  459. #define AfpVolDescToDtHdr(_pVolDesc, _pDtHdr) \
  460. { \
  461. (_pDtHdr)->dtp_Signature = AFP_SERVER_SIGNATURE; \
  462. (_pDtHdr)->dtp_Version = AFP_DESKTOP_VERSION; \
  463. (_pDtHdr)->dtp_cApplEnts = (_pVolDesc)->vds_cApplEnts; \
  464. (_pDtHdr)->dtp_cIconEnts = (_pVolDesc)->vds_cIconEnts; \
  465. }
  466. extern
  467. NTSTATUS
  468. AfpVolumeInit(
  469. VOID
  470. );
  471. extern
  472. PCONNDESC FASTCALL
  473. AfpConnectionReference(
  474. IN PSDA pSda,
  475. IN LONG VolId
  476. );
  477. extern
  478. PCONNDESC FASTCALL
  479. AfpConnectionReferenceAtDpc(
  480. IN PSDA pSda,
  481. IN LONG VolId
  482. );
  483. extern
  484. PCONNDESC FASTCALL
  485. AfpConnectionReferenceByPointer(
  486. IN PCONNDESC pConnDesc
  487. );
  488. extern
  489. PCONNDESC FASTCALL
  490. AfpReferenceConnectionById(
  491. IN DWORD ConnId
  492. );
  493. extern
  494. VOID FASTCALL
  495. AfpConnectionDereference(
  496. IN PCONNDESC pConnDesc
  497. );
  498. extern
  499. BOOLEAN FASTCALL
  500. AfpVolumeReference(
  501. IN PVOLDESC pVolDesc
  502. );
  503. extern
  504. PVOLDESC FASTCALL
  505. AfpVolumeReferenceByUpCaseName(
  506. IN PUNICODE_STRING pTargetName
  507. );
  508. extern
  509. AFPSTATUS FASTCALL
  510. AfpVolumeReferenceByPath(
  511. IN PUNICODE_STRING pFDPath,
  512. OUT PVOLDESC * ppVolDesc
  513. );
  514. extern
  515. VOID FASTCALL
  516. AfpVolumeDereference(
  517. IN PVOLDESC pVolDesc
  518. );
  519. extern
  520. BOOLEAN
  521. AfpVolumeMarkDt(
  522. IN PSDA pSda,
  523. IN PCONNDESC pConnDesc,
  524. IN DWORD OpenState
  525. );
  526. extern
  527. VOID FASTCALL
  528. AfpVolumeSetModifiedTime(
  529. IN PVOLDESC pVolDesc
  530. );
  531. extern
  532. AFPSTATUS FASTCALL
  533. AfpSendServerNotification(
  534. IN PVOLDESC pVolDesc
  535. );
  536. extern
  537. AFPSTATUS
  538. AfpConnectionOpen(
  539. IN PSDA pSda,
  540. IN PANSI_STRING pVolName,
  541. IN PANSI_STRING pVolPass,
  542. IN DWORD Bitmap,
  543. OUT PBYTE pVolParms
  544. );
  545. extern
  546. VOID FASTCALL
  547. AfpConnectionClose(
  548. IN PCONNDESC pConnDesc
  549. );
  550. extern
  551. USHORT FASTCALL
  552. AfpVolumeGetParmsReplyLength(
  553. IN DWORD Bitmap,
  554. IN USHORT NameLen
  555. );
  556. extern
  557. VOID
  558. AfpVolumePackParms(
  559. IN PSDA pSda,
  560. IN PVOLDESC pVolDesc,
  561. IN DWORD Bitmap,
  562. IN PBYTE pVolParms
  563. );
  564. extern
  565. AFPSTATUS
  566. AfpAdmWVolumeAdd(
  567. IN OUT PVOID Inbuf OPTIONAL,
  568. IN LONG OutBufLen OPTIONAL,
  569. OUT PVOID Outbuf OPTIONAL
  570. );
  571. extern
  572. AFPSTATUS
  573. AfpAdmWVolumeDelete(
  574. IN OUT PVOID InBuf OPTIONAL,
  575. IN LONG OutBufLen OPTIONAL,
  576. OUT PVOID OutBuf OPTIONAL
  577. );
  578. extern
  579. AFPSTATUS
  580. AfpAdmWConnectionClose(
  581. IN OUT PVOID InBuf OPTIONAL,
  582. IN LONG OutBufLen OPTIONAL,
  583. OUT PVOID OutBuf OPTIONAL
  584. );
  585. extern
  586. VOID
  587. AfpVolumeStopAllVolumes(
  588. VOID
  589. );
  590. extern
  591. AFPSTATUS FASTCALL
  592. AfpVolumeBeginIndexing(
  593. IN PVOLDESC pVolDesc
  594. );
  595. extern
  596. NTSTATUS FASTCALL
  597. AfpVolumePostChangeNotify(
  598. IN PVOLDESC pVolDesc
  599. );
  600. extern
  601. VOID FASTCALL
  602. AfpUpdateVolFreeSpaceAndModTime(
  603. IN PVOLDESC pVolDesc,
  604. IN BOOLEAN fUpdateModTime
  605. );
  606. extern
  607. AFPSTATUS FASTCALL
  608. AfpVolumeScavenger(
  609. IN PVOLDESC pVolDesc
  610. );
  611. extern
  612. BOOLEAN FASTCALL
  613. AfpVolumeAbortIndexing(
  614. IN PVOLDESC pVolDesc
  615. );
  616. extern
  617. BOOLEAN FASTCALL
  618. AfpVolumeStopIndexing(
  619. IN PVOLDESC pVolDesc,
  620. IN PVOL_NOTIFY pVolNotify
  621. );
  622. extern
  623. PVOL_NOTIFY
  624. afpAllocNotify(
  625. IN LONG Index,
  626. IN BOOLEAN fDir
  627. );
  628. extern
  629. VOID
  630. afpFreeNotify(
  631. IN PVOID pDfEntry
  632. );
  633. extern
  634. AFPSTATUS FASTCALL
  635. afpNotifyBlockAge(
  636. IN PPVOL_NOTIFY_BLOCK pBlockHead
  637. );
  638. extern
  639. VOID
  640. afpFreeNotifyBlockMemory(
  641. );
  642. VOID
  643. AfpVolumeUpdateIdDbAndDesktop(
  644. IN PVOLDESC pVolDesc,
  645. IN BOOLEAN WriteDt,
  646. IN BOOLEAN WriteIdDb,
  647. IN PIDDBHDR pIdDbHdr OPTIONAL
  648. );
  649. extern
  650. VOID FASTCALL
  651. afpActivateVolume(
  652. IN struct _VolDesc * pVolDesc
  653. );
  654. #ifdef VOLUME_LOCALS
  655. //
  656. // private routines
  657. //
  658. LOCAL AFPSTATUS FASTCALL
  659. afpVolumeCloseHandleAndFreeDesc(
  660. IN PVOLDESC pVolDesc
  661. );
  662. LOCAL AFPSTATUS FASTCALL
  663. afpVolumeAdd(
  664. IN PVOLDESC pVolDesc
  665. );
  666. LOCAL AFPSTATUS FASTCALL
  667. afpVolumeCheckForDuplicate(
  668. IN PVOLDESC pNewVol
  669. );
  670. LOCAL VOID FASTCALL
  671. afpVolumeGetNewIdAndLinkToList(
  672. IN PVOLDESC pVolDesc
  673. );
  674. LOCAL VOID FASTCALL
  675. afpNudgeCdfsVolume(
  676. IN PVOLDESC pVolDesc
  677. );
  678. LOCAL PCONNDESC FASTCALL
  679. afpConnectionReferenceById(
  680. IN DWORD ConnId
  681. );
  682. LOCAL VOID FASTCALL
  683. afpConnectionGetNewIdAndLinkToList(
  684. IN PCONNDESC pConnDesc
  685. );
  686. LOCAL NTSTATUS
  687. afpVolumeChangeNotifyComplete(
  688. IN PDEVICE_OBJECT pDeviceObject,
  689. IN PIRP pIrp,
  690. IN PVOLDESC pVolDesc
  691. );
  692. LOCAL DWORD afpNextConnId = 1; // Next conn id to assign to an open volume
  693. LOCAL LONG afpNumPostedNotifies = 0;
  694. // This is the smallest free volume id that is guaranteed to be free. Access
  695. // to this is via the AfpVolumeListLock.
  696. LOCAL LONG afpSmallestFreeVolId = 1;
  697. #endif // VOLUME_LOCALS
  698. #endif // _VOLUME_
  699.