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.

345 lines
7.2 KiB

  1. /*++
  2. Copyright (c) 1990 Microsoft Corporation
  3. Module Name:
  4. Common
  5. Abstract:
  6. Takes care of request which are common to all devices.
  7. Also contains any function which is common to two or more devices.
  8. Author:
  9. Ramon Juan San Andres (ramonsa) 26-Jun-1991
  10. Revision History:
  11. --*/
  12. #define _NTAPI_ULIB_
  13. #include "mode.hxx"
  14. #include "common.hxx"
  15. #include "com.hxx"
  16. #include "array.hxx"
  17. #include "arrayit.hxx"
  18. #include "stream.hxx"
  19. #include "system.hxx"
  20. #include "redir.hxx"
  21. #include "registry.hxx"
  22. #include "regvalue.hxx"
  23. BOOLEAN
  24. CommonHandler(
  25. IN PREQUEST_HEADER Request
  26. )
  27. /*++
  28. Routine Description:
  29. Calls all the device handlers with the supplied request.
  30. Arguments:
  31. Request - Supplies pointer to request
  32. Return Value:
  33. None.
  34. Notes:
  35. --*/
  36. {
  37. ULONG Device; // Current device
  38. REDIR_STATUS Status;
  39. PPATH DevicePath;
  40. REGISTRY Registry;
  41. DSTRING ParentName;
  42. DSTRING KeyName;
  43. ARRAY ValueArray;
  44. PARRAY_ITERATOR Iterator;
  45. ULONG ErrorCode;
  46. PCBYTE Data;
  47. DSTRING PortName;
  48. DSTRING QualifiedName;
  49. PREGISTRY_VALUE_ENTRY Value;
  50. DebugPtrAssert( Request );
  51. DebugAssert( Request->DeviceType == DEVICE_TYPE_ALL );
  52. //
  53. // If this is not a null request, then we pass this request to all
  54. // device handlers. Note that this means that a device handler must
  55. // NOT modify the request, otherwise the next device handler would
  56. // get a corrupted request.
  57. //
  58. if ( Request->RequestType != REQUEST_TYPE_NULL ) {
  59. //
  60. // LPT devices
  61. //
  62. for ( Device = 1; Device <= LAST_LPT; Device++ ) {
  63. if ( IsAValidLptDevice( DEVICE_TYPE_LPT, Device, &DevicePath ) ||
  64. REDIR::IsRedirected( &Status, DevicePath )
  65. ) {
  66. Request->DeviceType = DEVICE_TYPE_LPT;
  67. Request->DeviceNumber = Device;
  68. //
  69. // Have it serviced
  70. //
  71. DeviceHandler[ DEVICE_TYPE_LPT ]( Request );
  72. DELETE( DevicePath );
  73. }
  74. }
  75. //
  76. // COM devices
  77. //
  78. if ( ParentName.Initialize( "" ) &&
  79. KeyName.Initialize( COMM_KEY_NAME ) &&
  80. ValueArray.Initialize() &&
  81. Registry.Initialize() &&
  82. Registry.QueryValues(
  83. PREDEFINED_KEY_LOCAL_MACHINE,
  84. &ParentName,
  85. &KeyName,
  86. &ValueArray,
  87. &ErrorCode
  88. ) ) {
  89. if ( Iterator = (PARRAY_ITERATOR)ValueArray.QueryIterator() ) {
  90. while ( Value = (PREGISTRY_VALUE_ENTRY)(Iterator->GetNext() ) ) {
  91. if ( Value->GetData( &Data ) ) {
  92. if ( PortName.Initialize( (PWSTR)Data ) &&
  93. QualifiedName.Initialize( L"\\\\.\\" ) &&
  94. QualifiedName.Strcat( &PortName ) ) {
  95. if ( SYSTEM::QueryFileType( &QualifiedName ) == CharFile ) {
  96. Request->DeviceType = DEVICE_TYPE_COM;
  97. Request->DeviceName = &PortName;
  98. DeviceHandler[ DEVICE_TYPE_COM ]( Request );
  99. }
  100. }
  101. }
  102. }
  103. DELETE( Iterator );
  104. }
  105. }
  106. //
  107. // CON device
  108. //
  109. Request->DeviceType = DEVICE_TYPE_CON;
  110. Request->DeviceNumber = 1;
  111. DeviceHandler[ DEVICE_TYPE_CON ]( Request );
  112. }
  113. return TRUE;
  114. }
  115. BOOLEAN
  116. IsAValidDevice (
  117. IN DEVICE_TTYPE DeviceType,
  118. IN ULONG DeviceNumber,
  119. OUT PPATH *DevicePathPointer
  120. )
  121. /*++
  122. Routine Description:
  123. Determines if a certain device exists and optionally creates a path
  124. for the device.
  125. Arguments:
  126. DeviceType - Supplies the type of device
  127. DeviceNumber - Supplies the device number
  128. DeviceName - Supplies a pointer to a pointer to the path for
  129. the device.
  130. Return Value:
  131. BOOLEAN - TRUE if the device exists,
  132. FALSE otherwise.
  133. Notes:
  134. --*/
  135. {
  136. DSTRING DeviceName;
  137. DSTRING QualifiedDeviceName;
  138. DSTRING Number;
  139. CHNUM Index;
  140. FILE_TYPE DriveType;
  141. PPATH DevicePath;
  142. //
  143. // Determine what device we're working with.
  144. //
  145. switch ( DeviceType ) {
  146. case DEVICE_TYPE_COM:
  147. DeviceName.Initialize("COM#");
  148. break;
  149. case DEVICE_TYPE_LPT:
  150. DeviceName.Initialize("LPT#");
  151. break;
  152. case DEVICE_TYPE_CON:
  153. DeviceName.Initialize("CON");
  154. break;
  155. default:
  156. DebugAssert( FALSE );
  157. }
  158. //
  159. // All devices (except the console) have a device number
  160. //
  161. if ( DeviceType != DEVICE_TYPE_CON ) {
  162. //
  163. // Get the device number in string form
  164. //
  165. Number.Initialize( DeviceNumber );
  166. //
  167. // Now substitute the matchnumber character with the number
  168. //
  169. Index = DeviceName.Strchr( '#' );
  170. DebugAssert( Index != INVALID_CHNUM );
  171. DeviceName.Replace( Index, 1, &Number );
  172. }
  173. //
  174. // We have the device name, gets its type.
  175. //
  176. QualifiedDeviceName.Initialize( "\\\\.\\" );
  177. QualifiedDeviceName.Strcat( &DeviceName );
  178. DriveType = SYSTEM::QueryFileType( &QualifiedDeviceName );
  179. //
  180. // If the caller wants a path, make it.
  181. //
  182. if ( DevicePathPointer ) {
  183. DevicePath = NEW PATH;
  184. DebugPtrAssert( DevicePath );
  185. if ( DevicePath ) {
  186. DevicePath->Initialize( &DeviceName );
  187. }
  188. *DevicePathPointer = DevicePath;
  189. }
  190. //
  191. // Now return whether the device is valid or not
  192. //
  193. return DriveType == CharFile;
  194. }
  195. BOOLEAN
  196. WriteStatusHeader (
  197. IN PCPATH DevicePath
  198. )
  199. /*++
  200. Routine Description:
  201. Write the header for a status block.
  202. Arguments:
  203. DevicePath - Supplies the device path
  204. Return Value:
  205. BOOLEAN - TRUE if header written
  206. FALSE otherwise.
  207. Notes:
  208. --*/
  209. {
  210. PWSTRING Header;
  211. CHNUM Index;
  212. Header = QueryMessageString( MODE_MESSAGE_STATUS );
  213. if ( !Header ) {
  214. DisplayMessageAndExit( MODE_ERROR_NO_MEMORY, NULL, (ULONG)EXIT_ERROR );
  215. }
  216. //
  217. // Replace the match-all character in the header with the device
  218. // path.
  219. //
  220. Index = Header->Strchr( '*' );
  221. DebugAssert( Index != INVALID_CHNUM );
  222. Header->Replace( Index, 1, DevicePath->GetPathString() );
  223. //
  224. // Display the header
  225. //
  226. Get_Standard_Output_Stream()->WriteChar( '\r' );
  227. Get_Standard_Output_Stream()->WriteChar( '\n' );
  228. Get_Standard_Output_Stream()->WriteString( Header );
  229. Get_Standard_Output_Stream()->WriteChar( '\r' );
  230. Get_Standard_Output_Stream()->WriteChar( '\n' );
  231. //
  232. // Underline it
  233. //
  234. for (Index = 0; Index < Header->QueryChCount(); Index++) {
  235. Header->SetChAt( '-', Index );
  236. }
  237. Get_Standard_Output_Stream()->WriteString( Header );
  238. Get_Standard_Output_Stream()->WriteChar( '\r' );
  239. Get_Standard_Output_Stream()->WriteChar( '\n' );
  240. DELETE( Header );
  241. return TRUE;
  242. }