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.

309 lines
5.5 KiB

  1. /*++
  2. Copyright (c) 1999-2001 Microsoft Corporation. All Rights Reserved.
  3. Module Name:
  4. device.c
  5. Abstract:
  6. Author:
  7. Joseph Ballantyne
  8. Environment:
  9. Kernel Mode
  10. Revision History:
  11. --*/
  12. #define IRPMJFUNCDESC
  13. #define WANTVXDWRAPS
  14. #include "common.h"
  15. #include "rtp.h"
  16. #include "log.h"
  17. #ifndef UNDER_NT
  18. ULONG RT_Init_VxD(VOID);
  19. #define STR_DEVICENAME TEXT(L"\\Device\\Rt")
  20. #define STR_REGISTRY TEXT(L"\\REGISTRY\\Machine\\Software\\Microsoft\\RealTime")
  21. #define STR_RTDISABLE TEXT(L"DisableRtExecutive")
  22. #else
  23. //#define OFFBYDEFAULT 1
  24. #define STR_DEVICENAME TEXT("\\Device\\Rt")
  25. #define STR_REGISTRY TEXT("\\REGISTRY\\Machine\\Software\\Microsoft\\RealTime")
  26. #define STR_RTDISABLE TEXT("DisableRtExecutive")
  27. #ifdef OFFBYDEFAULT
  28. #define STR_RTENABLE TEXT("EnableRtExecutive")
  29. #endif
  30. #endif
  31. #define RT_LOG_SIZE 32 // This MUST be a power of 2.
  32. #ifdef OFFBYDEFAULT
  33. DWORD RtEnable=0;
  34. #endif
  35. DWORD RtDisable=0;
  36. LONG RtInitialized=0;
  37. PDEVICE_OBJECT pdo=NULL;
  38. PRTLOGHEADER RtLog=NULL;
  39. VOID
  40. DriverUnload (
  41. IN PDRIVER_OBJECT DriverObject
  42. )
  43. {
  44. Break();
  45. }
  46. NTSTATUS
  47. RtpInitialize (
  48. VOID
  49. )
  50. {
  51. RTL_QUERY_REGISTRY_TABLE QueryTable[] = {
  52. {
  53. NULL, // No callback routine
  54. RTL_QUERY_REGISTRY_DIRECT,
  55. NULL,
  56. &RtDisable,
  57. REG_DWORD,
  58. &RtDisable,
  59. sizeof(RtDisable)
  60. },
  61. #ifdef OFFBYDEFAULT
  62. {
  63. NULL, // No callback routine
  64. RTL_QUERY_REGISTRY_DIRECT,
  65. NULL,
  66. &RtEnable,
  67. REG_DWORD,
  68. &RtEnable,
  69. sizeof(RtEnable)
  70. },
  71. #endif
  72. {
  73. NULL, // Null entry
  74. 0,
  75. NULL,
  76. NULL,
  77. 0,
  78. NULL,
  79. 0
  80. }
  81. };
  82. UNICODE_STRING usRegistry;
  83. UNICODE_STRING usRtDisable;
  84. #ifdef OFFBYDEFAULT
  85. UNICODE_STRING usRtEnable;
  86. #endif
  87. #ifdef UNDER_NT
  88. PHYSICAL_ADDRESS Physical;
  89. #endif
  90. ULONG i;
  91. //Break();
  92. // Prepare to query the registry
  93. RtlInitUnicodeString( &usRegistry, STR_REGISTRY );
  94. RtlInitUnicodeString( &usRtDisable, STR_RTDISABLE );
  95. #ifdef OFFBYDEFAULT
  96. RtlInitUnicodeString( &usRtEnable, STR_RTENABLE );
  97. #endif
  98. QueryTable[0].Name = usRtDisable.Buffer;
  99. #ifdef OFFBYDEFAULT
  100. QueryTable[1].Name = usRtEnable.Buffer;
  101. #endif
  102. // Query registry to see if we should allow RT to run.
  103. RtlQueryRegistryValues(
  104. RTL_REGISTRY_ABSOLUTE,
  105. usRegistry.Buffer,
  106. &(QueryTable[0]),
  107. NULL,
  108. NULL
  109. );
  110. // Now setup the realtime logging buffer.
  111. #ifdef UNDER_NT
  112. Physical.QuadPart=-1I64;
  113. RtLog=(PRTLOGHEADER)MmAllocateContiguousMemory(PAGE_SIZE*(RT_LOG_SIZE+1), Physical);
  114. #else
  115. RtLog=(PRTLOGHEADER)ExAllocatePool(NonPagedPool, PAGE_SIZE*(RT_LOG_SIZE+1));
  116. #endif
  117. // Failing to allocate the RtLog is not fatal. If we get it, set it up.
  118. if (RtLog) {
  119. RtLog->Buffer=(PCHAR)RtLog+PAGE_SIZE;
  120. // The output or print buffersize MUST be a power of 2. This is because the read and write
  121. // locations increment constantly and DO NOT WRAP with the buffer size. That is intentional
  122. // because it makes checking whether there is data in the buffer or not very simple and atomic.
  123. // However, the read and write locations will wrap on 32 bit boundaries. This is OK as long as
  124. // our buffersize divides into 2^32 evenly, which it always will if it is a power of 2.
  125. RtLog->BufferSize=PAGE_SIZE*RT_LOG_SIZE;
  126. RtLog->WriteLocation=0;
  127. // Mark every slot in the output buffer empty.
  128. for (i=0; i<RtLog->BufferSize; i+=RT_LOG_ENTRY_SIZE) {
  129. ((ULONG *)RtLog->Buffer)[i/sizeof(ULONG)]=NODATA;
  130. }
  131. }
  132. #ifdef OFFBYDEFAULT
  133. if (RtEnable) {
  134. #endif
  135. // Initialize if RT not disabled and we have not already initialized.
  136. if (!RtDisable && InterlockedIncrement(&RtInitialized)==1) {
  137. #ifndef UNDER_NT
  138. RT_Init_VxD();
  139. #endif
  140. SetupRealTimeThreads();
  141. }
  142. #ifdef OFFBYDEFAULT
  143. }
  144. #endif
  145. return STATUS_SUCCESS;
  146. }
  147. NTSTATUS
  148. DriverEntry (
  149. IN PDRIVER_OBJECT DriverObject,
  150. IN PUNICODE_STRING usRegistryPathName
  151. )
  152. {
  153. //dprintf(("DriverEntry Enter (DriverObject = %x)", DriverObject));
  154. DriverObject->DriverUnload = DriverUnload;
  155. // For now, keep RT loaded always.
  156. ObReferenceObject(DriverObject);
  157. #if 0
  158. // We will need to create a device in order to be able to pull
  159. // RT statistics down into user mode.
  160. {
  161. UNICODE_STRING usDeviceName;
  162. RtlInitUnicodeString( &usDeviceName, STR_DEVICENAME );
  163. IoCreateDevice(DriverObject,0,&usDeviceName,0,0,FALSE,&pdo);
  164. }
  165. #endif
  166. return RtpInitialize();
  167. }
  168. NTSTATUS
  169. DllInitialize (
  170. IN PUNICODE_STRING RegistryPath
  171. )
  172. {
  173. #ifdef UNDER_NT
  174. // On NT, we do NOT load until someone linked to us loads. That way
  175. // unless we are needed, we stay out of the way.
  176. return RtpInitialize();
  177. #else
  178. // On Win9x because Rt hooks the IDT, it MUST be loaded at boot time.
  179. // This code is here to catch if we ever get loaded as a DLL which will only
  180. // happen if we did NOT get properly loaded at boot time.
  181. // In debug on Win9x, make SURE our failure to load properly at boot is noticed.
  182. #if DEBUG
  183. KeBugCheckEx(0x1baddeed,0,0,0,0);
  184. #endif // DEBUG
  185. // In retail on Win9x be as nice as possible. None of our API's will succeed,
  186. // but we let people that are linked to us load without failing.
  187. return STATUS_SUCCESS;
  188. #endif // UNDER_NT
  189. }