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.

611 lines
16 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. sac.h
  5. Abstract:
  6. This is the local header file for SAC. It includes all other
  7. necessary header files for this driver.
  8. Author:
  9. Sean Selitrennikoff (v-seans) - Jan 11, 1999
  10. Revision History:
  11. --*/
  12. #ifndef _SACP_
  13. #define _SACP_
  14. #pragma warning(disable:4214) // bit field types other than int
  15. #pragma warning(disable:4201) // nameless struct/union
  16. #pragma warning(disable:4127) // condition expression is constant
  17. #pragma warning(disable:4115) // named type definition in parentheses
  18. //#pragma warning(disable:4206) // translation unit empty
  19. //#pragma warning(disable:4706) // assignment within conditional
  20. //#pragma warning(disable:4324) // structure was padded
  21. //#pragma warning(disable:4328) // greater alignment than needed
  22. #include <stdio.h>
  23. #include <ntosp.h>
  24. #include <zwapi.h>
  25. #include <hdlsblk.h>
  26. #include <hdlsterm.h>
  27. #include "sacmsg.h"
  28. #include <ntddsac.h>
  29. //
  30. // Debug spew control
  31. //
  32. #if DBG
  33. extern ULONG SACDebug;
  34. #define SAC_DEBUG_FUNC_TRACE 0x0001
  35. #define SAC_DEBUG_FAILS 0x0004
  36. #define SAC_DEBUG_RECEIVE 0x0008
  37. #define SAC_DEBUG_FUNC_TRACE_LOUD 0x2000 // Warning! This could get loud!
  38. #define SAC_DEBUG_MEM 0x1000 // Warning! This could get loud!
  39. #define IF_SAC_DEBUG(x, y) if ((x) & SACDebug) { y; }
  40. #else
  41. #define IF_SAC_DEBUG(x, y)
  42. #endif
  43. #define ASSERT_STATUS(_C, _S)\
  44. ASSERT((_C));\
  45. if (!(_C)) {\
  46. return(_S);\
  47. }
  48. #if 0
  49. //
  50. // General lock (mutex) management macros
  51. //
  52. typedef struct _SAC_LOCK {
  53. ULONG RefCount;
  54. KMUTEX Mutex;
  55. } SAC_LOCK, *PSAC_LOCK;
  56. #define INITIALIZE_LOCK(_l) \
  57. KeInitializeMutex( \
  58. &(_l.Mutex), \
  59. 0 \
  60. ); \
  61. _l.RefCount = 0;
  62. #define LOCK_IS_SIGNALED(_l) \
  63. (KeReadStateMutex(&(_l.Mutex)) == 1 ? TRUE : FALSE)
  64. #define LOCK_HAS_ZERO_REF_COUNT(_l) \
  65. (_l.RefCount == 0 ? TRUE : FALSE)
  66. #define ACQUIRE_LOCK(_l) \
  67. KeWaitForMutexObject( \
  68. &(_l.Mutex), \
  69. Executive, \
  70. KernelMode, \
  71. FALSE, \
  72. NULL \
  73. ); \
  74. ASSERT(_l.RefCount == 0); \
  75. InterlockedIncrement(&(_l.RefCount));
  76. #define RELEASE_LOCK(_l) \
  77. ASSERT(_l.RefCount == 1); \
  78. InterlockedDecrement(&(_l.RefCount)); \
  79. KeReleaseMutex( \
  80. &(_l.Mutex), \
  81. FALSE \
  82. );
  83. #else
  84. //
  85. // General lock (mutex) management macros
  86. //
  87. typedef struct _SAC_LOCK {
  88. ULONG RefCount;
  89. KSEMAPHORE Lock;
  90. } SAC_LOCK, *PSAC_LOCK;
  91. #define INITIALIZE_LOCK(_l) \
  92. KeInitializeSemaphore( \
  93. &(_l.Lock), \
  94. 1, \
  95. 1 \
  96. ); \
  97. _l.RefCount = 0;
  98. #define LOCK_IS_SIGNALED(_l) \
  99. (KeReadStateSemaphore(&(_l.Lock)) == 1 ? TRUE : FALSE)
  100. #define LOCK_HAS_ZERO_REF_COUNT(_l) \
  101. (_l.RefCount == 0 ? TRUE : FALSE)
  102. #define ACQUIRE_LOCK(_l) \
  103. KeWaitForSingleObject( \
  104. &(_l.Lock), \
  105. Executive, \
  106. KernelMode, \
  107. FALSE, \
  108. NULL \
  109. ); \
  110. ASSERT(_l.RefCount == 0); \
  111. InterlockedIncrement((volatile long *)&(_l.RefCount));
  112. #define RELEASE_LOCK(_l) \
  113. ASSERT(_l.RefCount == 1); \
  114. InterlockedDecrement((volatile long *)&(_l.RefCount)); \
  115. KeReleaseSemaphore( \
  116. &(_l.Lock), \
  117. IO_NO_INCREMENT, \
  118. 1, \
  119. FALSE \
  120. );
  121. #endif
  122. //
  123. // This really belongs in ntdef or someplace like that...
  124. //
  125. typedef CONST UCHAR *LPCUCHAR, *PCUCHAR;
  126. #include "channel.h"
  127. //
  128. // this macro ensures that we assert if we buffer overrun during the swprintf
  129. //
  130. // NOTE: 1 is added to the length to acct for UNICODE_NULL
  131. //
  132. #define SAFE_SWPRINTF(_size, _p)\
  133. { \
  134. ULONG l; \
  135. l = swprintf _p; \
  136. ASSERT(((l+1)*sizeof(WCHAR)) <= _size); \
  137. }
  138. //
  139. // NOTE: 1 is added to the length to acct for UNICODE_NULL
  140. //
  141. #define SAFE_WCSCPY(_size, _d, _s) \
  142. { \
  143. if (_size >= 2) { \
  144. ULONG l; \
  145. l = (ULONG)wcslen(_s); \
  146. ASSERT(((l+1)*sizeof(WCHAR)) <= _size); \
  147. wcsncpy(_d,_s,(_size / sizeof(WCHAR))); \
  148. (_d)[(_size / sizeof(WCHAR)) - 1] = UNICODE_NULL; \
  149. } else { \
  150. ASSERT(0); \
  151. } \
  152. }
  153. #ifndef max
  154. #define max(a,b) (((a) > (b)) ? (a) : (b))
  155. #endif
  156. #ifndef min
  157. #define min(a,b) (((a) < (b)) ? (a) : (b))
  158. #endif
  159. //
  160. // Machine Information table and routines.
  161. //
  162. #define INIT_OBJA(Obja,UnicodeString,UnicodeText) \
  163. \
  164. RtlInitUnicodeString((UnicodeString),(UnicodeText)); \
  165. \
  166. InitializeObjectAttributes( \
  167. (Obja), \
  168. (UnicodeString), \
  169. OBJ_CASE_INSENSITIVE, \
  170. NULL, \
  171. NULL \
  172. )
  173. //
  174. // common xml header
  175. //
  176. #define XML_VERSION_HEADER L"<?xml version=\"1.0\"?>\r\n"
  177. //
  178. // Device name
  179. //
  180. #define SAC_DEVICE_NAME L"\\Device\\SAC"
  181. #define SAC_DOSDEVICE_NAME L"\\DosDevices\\SAC"
  182. //
  183. // Memory tags
  184. //
  185. #define ALLOC_POOL_TAG ((ULONG)'ApcR')
  186. #define INITIAL_POOL_TAG ((ULONG)'IpcR')
  187. //#define IRP_POOL_TAG ((ULONG)'JpcR')
  188. #define SECURITY_POOL_TAG ((ULONG)'SpcR')
  189. //
  190. // SAC internal Memory tags
  191. //
  192. #define FREE_POOL_TAG ((ULONG)'FpcR')
  193. #define GENERAL_POOL_TAG ((ULONG)'GpcR')
  194. #define CHANNEL_POOL_TAG ((ULONG)'CpcR')
  195. //
  196. // Other defines
  197. //
  198. #define MEMORY_INCREMENT 0x1000
  199. #define DEFAULT_IRP_STACK_SIZE 16
  200. #define DEFAULT_PRIORITY_BOOST 2
  201. #define SAC_SUBMIT_IOCTL 1
  202. #define SAC_PROCESS_INPUT 2
  203. #define SAC_CHANGE_CHANNEL 3
  204. #define SAC_DISPLAY_CHANNEL 4
  205. #define SAC_NO_OP 0
  206. #define SAC_RETRY_GAP 10
  207. #define SAC_PROCESS_SERIAL_PORT_BUFFER 20
  208. //
  209. // Context for each device created
  210. //
  211. typedef struct _SAC_DEVICE_CONTEXT {
  212. PDEVICE_OBJECT DeviceObject; // back pointer to the device object.
  213. BOOLEAN InitializedAndReady; // Is this device ready to go?
  214. BOOLEAN Processing; // Is something being processed on this device?
  215. BOOLEAN ExitThread; // Should the worker thread exit?
  216. CCHAR PriorityBoost; // boost to priority for completions.
  217. PKPROCESS SystemProcess; // context for grabbing handles
  218. PSECURITY_DESCRIPTOR AdminSecurityDescriptor;
  219. KSPIN_LOCK SpinLock; // Used to lock this data structure for access.
  220. KEVENT UnloadEvent; // Used to signal the thread trying to unload to continue processing.
  221. KEVENT ProcessEvent; // Used to signal worker thread to process the next request.
  222. HANDLE ThreadHandle; // Handle for the worker thread.
  223. KEVENT ThreadExitEvent; // Used to main thread the worker thread is exiting.
  224. KTIMER Timer; // Used to poll for user input.
  225. KDPC Dpc; // Used with the above timer.
  226. LIST_ENTRY IrpQueue; // List of IRPs to be processed.
  227. } SAC_DEVICE_CONTEXT, * PSAC_DEVICE_CONTEXT;
  228. //
  229. // Structure to hold general machine information
  230. //
  231. typedef struct _MACHINE_INFORMATION {
  232. PWSTR MachineName;
  233. PWSTR GUID;
  234. PWSTR ProcessorArchitecture;
  235. PWSTR OSVersion;
  236. PWSTR OSBuildNumber;
  237. PWSTR OSProductType;
  238. PWSTR OSServicePack;
  239. } MACHINE_INFORMATION, *PMACHINE_INFORMATION;
  240. //
  241. // IoMgrHandleEvent event types
  242. //
  243. typedef enum _IO_MGR_EVENT {
  244. IO_MGR_EVENT_CHANNEL_CREATE = 0,
  245. IO_MGR_EVENT_CHANNEL_CLOSE,
  246. IO_MGR_EVENT_CHANNEL_WRITE,
  247. IO_MGR_EVENT_REGISTER_SAC_CMD_EVENT,
  248. IO_MGR_EVENT_UNREGISTER_SAC_CMD_EVENT,
  249. IO_MGR_EVENT_SHUTDOWN
  250. } IO_MGR_EVENT;
  251. //
  252. // IO Manager function types
  253. //
  254. typedef NTSTATUS
  255. (*IO_MGR_HANDLE_EVENT)(
  256. IN IO_MGR_EVENT Event,
  257. IN PSAC_CHANNEL Channel,
  258. IN PVOID Data
  259. );
  260. typedef NTSTATUS
  261. (*IO_MGR_INITITIALIZE)(
  262. VOID
  263. );
  264. typedef NTSTATUS
  265. (*IO_MGR_SHUTDOWN)(
  266. VOID
  267. );
  268. typedef VOID
  269. (*IO_MGR_WORKER)(
  270. IN PSAC_DEVICE_CONTEXT DeviceContext
  271. );
  272. typedef BOOLEAN
  273. (*IO_MGR_IS_WRITE_ENABLED)(
  274. IN PSAC_CHANNEL Channel
  275. );
  276. typedef NTSTATUS
  277. (*IO_MGR_WRITE_DATA)(
  278. IN PSAC_CHANNEL Channel,
  279. IN PCUCHAR Buffer,
  280. IN ULONG BufferSize
  281. );
  282. typedef NTSTATUS
  283. (*IO_MGR_FLUSH_DATA)(
  284. IN PSAC_CHANNEL Channel
  285. );
  286. //
  287. // Global data
  288. //
  289. //
  290. // Function pointers to the routines that implement the I/O Manager behavior
  291. //
  292. extern IO_MGR_HANDLE_EVENT IoMgrHandleEvent;
  293. extern IO_MGR_INITITIALIZE IoMgrInitialize;
  294. extern IO_MGR_SHUTDOWN IoMgrShutdown;
  295. extern IO_MGR_WORKER IoMgrWorkerProcessEvents;
  296. extern IO_MGR_IS_WRITE_ENABLED IoMgrIsWriteEnabled;
  297. extern IO_MGR_WRITE_DATA IoMgrWriteData;
  298. extern IO_MGR_FLUSH_DATA IoMgrFlushData;
  299. extern PMACHINE_INFORMATION MachineInformation;
  300. extern BOOLEAN GlobalDataInitialized;
  301. extern BOOLEAN GlobalPagingNeeded;
  302. extern BOOLEAN IoctlSubmitted;
  303. extern LONG ProcessingType;
  304. extern HANDLE SACEventHandle;
  305. extern PKEVENT SACEvent;
  306. //
  307. // Enable the ability to check that the process/service that
  308. // registered is the one that is unregistering
  309. //
  310. #define ENABLE_SERVICE_FILE_OBJECT_CHECKING 1
  311. //
  312. // Enable user-specified feature control for cmd sessions
  313. //
  314. #define ENABLE_CMD_SESSION_PERMISSION_CHECKING 1
  315. //
  316. // Enable the ability to override the service start type
  317. // based on the cmd session permissions
  318. //
  319. // Note: ENABLE_CMD_SESSION_PERMISSION_CHECKING must be 1
  320. // for this feature to work
  321. //
  322. #define ENABLE_SACSVR_START_TYPE_OVERRIDE 1
  323. //
  324. // Globals controlling if command console channels may be launched
  325. //
  326. #if ENABLE_CMD_SESSION_PERMISSION_CHECKING
  327. extern BOOLEAN CommandConsoleLaunchingEnabled;
  328. #define IsCommandConsoleLaunchingEnabled() (CommandConsoleLaunchingEnabled)
  329. #endif
  330. //
  331. // The UTF8 encoding buffer
  332. //
  333. // Note: this buffer used during driver initialization,
  334. // the Console Manager and VTUTF8 channels.
  335. // It is safe to do this because the writes of these
  336. // modules never overlap.
  337. // The console manager uses the CURRENT CHANNEL LOCK
  338. // to ensure that no two modules write out at the same
  339. // time.
  340. //
  341. extern PUCHAR Utf8ConversionBuffer;
  342. extern ULONG Utf8ConversionBufferSize;
  343. //
  344. // Define the max # of Unicode chars that can be translated with the
  345. // given size of the utf8 translation buffer
  346. //
  347. #define MAX_UTF8_ENCODE_BLOCK_LENGTH ((Utf8ConversionBufferSize / 3) - 1)
  348. //
  349. // Globals for managing incremental UTF8 encoding for VTUTF8 channels
  350. //
  351. // Note: it is safe to use this as a global because only
  352. // one channel ever has the focus. Hence, no two threads
  353. // should ever be decoding UFT8 at the same time.
  354. //
  355. extern WCHAR IncomingUnicodeValue;
  356. extern UCHAR IncomingUtf8ConversionBuffer[3];
  357. //
  358. // Command console event info:
  359. //
  360. // Pointers to the event handles for the Command Console event service
  361. //
  362. extern PVOID RequestSacCmdEventObjectBody;
  363. extern PVOID RequestSacCmdEventWaitObjectBody;
  364. extern PVOID RequestSacCmdSuccessEventObjectBody;
  365. extern PVOID RequestSacCmdSuccessEventWaitObjectBody;
  366. extern PVOID RequestSacCmdFailureEventObjectBody;
  367. extern PVOID RequestSacCmdFailureEventWaitObjectBody;
  368. extern BOOLEAN HaveUserModeServiceCmdEventInfo;
  369. extern KMUTEX SACCmdEventInfoMutex;
  370. #if ENABLE_SERVICE_FILE_OBJECT_CHECKING
  371. extern PFILE_OBJECT ServiceProcessFileObject;
  372. #endif
  373. //
  374. // Has the user-mode service registered?
  375. //
  376. #define UserModeServiceHasRegisteredCmdEvent() (HaveUserModeServiceCmdEventInfo)
  377. //
  378. // Serial Port Buffer globals
  379. //
  380. //
  381. // Size of the serial port buffer
  382. //
  383. #define SERIAL_PORT_BUFFER_LENGTH 1024
  384. #define SERIAL_PORT_BUFFER_SIZE (SERIAL_PORT_BUFFER_LENGTH * sizeof(UCHAR))
  385. //
  386. // Serial port buffer and producer/consumer indices
  387. //
  388. // Note: there can be only one consumer
  389. //
  390. extern PUCHAR SerialPortBuffer;
  391. extern ULONG SerialPortProducerIndex;
  392. extern ULONG SerialPortConsumerIndex;
  393. //
  394. // Memory management routines
  395. //
  396. #define ALLOCATE_POOL(b,t) MyAllocatePool( b, t, __FILE__, __LINE__ )
  397. #define SAFE_FREE_POOL(_b) \
  398. if (*_b) { \
  399. FREE_POOL(_b); \
  400. }
  401. #define FREE_POOL(b) MyFreePool( b )
  402. //
  403. //
  404. //
  405. BOOLEAN
  406. InitializeMemoryManagement(
  407. VOID
  408. );
  409. VOID
  410. FreeMemoryManagement(
  411. VOID
  412. );
  413. PVOID
  414. MyAllocatePool(
  415. IN SIZE_T NumberOfBytes,
  416. IN ULONG Tag,
  417. IN PCHAR FileName,
  418. IN ULONG LineNumber
  419. );
  420. VOID
  421. MyFreePool(
  422. IN PVOID Pointer
  423. );
  424. //
  425. // Initialization routines.
  426. //
  427. BOOLEAN
  428. InitializeGlobalData(
  429. IN PUNICODE_STRING RegistryPath,
  430. IN PDRIVER_OBJECT DriverObject
  431. );
  432. VOID
  433. FreeGlobalData(
  434. VOID
  435. );
  436. BOOLEAN
  437. InitializeDeviceData(
  438. PDEVICE_OBJECT DeviceObject
  439. );
  440. VOID
  441. FreeDeviceData(
  442. PDEVICE_OBJECT DeviceContext
  443. );
  444. VOID
  445. InitializeCmdEventInfo(
  446. VOID
  447. );
  448. //
  449. // Dispatch routines
  450. //
  451. NTSTATUS
  452. Dispatch(
  453. IN PDEVICE_OBJECT DeviceObject,
  454. IN PIRP Irp
  455. );
  456. NTSTATUS
  457. DispatchDeviceControl(
  458. IN PDEVICE_OBJECT DeviceObject,
  459. IN PIRP Irp
  460. );
  461. NTSTATUS
  462. DispatchShutdownControl(
  463. IN PDEVICE_OBJECT DeviceObject,
  464. IN PIRP Irp
  465. );
  466. VOID
  467. UnloadHandler(
  468. IN PDRIVER_OBJECT DriverObject
  469. );
  470. NTSTATUS
  471. DispatchSend(
  472. IN PSAC_DEVICE_CONTEXT DeviceContext
  473. );
  474. VOID
  475. DoDeferred(
  476. IN PSAC_DEVICE_CONTEXT DeviceContext
  477. );
  478. //
  479. // Worker thread routines.
  480. //
  481. VOID
  482. TimerDpcRoutine(
  483. IN struct _KDPC *Dpc,
  484. IN PVOID DeferredContext,
  485. IN PVOID SystemArgument1,
  486. IN PVOID SystemArgument2
  487. );
  488. VOID
  489. WorkerProcessEvents(
  490. IN PSAC_DEVICE_CONTEXT DeviceContext
  491. );
  492. #include "util.h"
  493. //
  494. // Channel routines
  495. //
  496. #include "xmlmgr.h"
  497. #include "conmgr.h"
  498. #include "chanmgr.h"
  499. #include "vtutf8chan.h"
  500. #include "rawchan.h"
  501. #include "cmdchan.h"
  502. #endif // ndef _SACP_