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.

280 lines
5.8 KiB

  1. /********************************************************************/
  2. /** Copyright(c) 1989 Microsoft Corporation. **/
  3. /********************************************************************/
  4. //***
  5. //
  6. // Filename: util.c
  7. //
  8. // Description: This module contains misc. utility routines.
  9. //
  10. // History: May 11,1992. NarenG Created original version.
  11. //
  12. #include <nt.h>
  13. #include <ntioapi.h>
  14. #include <ntrtl.h>
  15. #include <ntobapi.h>
  16. #include <nturtl.h> // needed for winbase.h
  17. #include <afpsvcp.h>
  18. #define PRIVILEGE_BUF_SIZE 512
  19. //**
  20. //
  21. // Call: AfpFSDOpen
  22. //
  23. // Returns: 0 - success
  24. // non-zero returns mapped to WIN32 errors.
  25. //
  26. // Description: Opens the AFP file system driver. It is opened in exclusive
  27. // mode.
  28. // NTOpenFile is used instead of it's WIN32 counterpart, since
  29. // WIN32 always prpends \Dos\devices to the file name. The AFP FSD
  30. // driver is not a dos device.
  31. //
  32. DWORD
  33. AfpFSDOpen(
  34. OUT PHANDLE phFSD
  35. )
  36. {
  37. NTSTATUS ntRetCode;
  38. OBJECT_ATTRIBUTES ObjectAttributes;
  39. UNICODE_STRING FSDName;
  40. IO_STATUS_BLOCK IoStatus;
  41. RtlInitUnicodeString( &FSDName, AFPSERVER_DEVICE_NAME );
  42. InitializeObjectAttributes( &ObjectAttributes,
  43. &FSDName,
  44. OBJ_CASE_INSENSITIVE,
  45. NULL,
  46. NULL );
  47. ntRetCode = NtOpenFile(phFSD,
  48. SYNCHRONIZE,
  49. &ObjectAttributes,
  50. &IoStatus,
  51. #ifdef DBG
  52. FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
  53. #else
  54. 0,
  55. #endif
  56. FILE_SYNCHRONOUS_IO_NONALERT );
  57. if ( NT_SUCCESS( ntRetCode ) )
  58. return( NO_ERROR );
  59. else
  60. return( RtlNtStatusToDosError( ntRetCode ) );
  61. }
  62. //**
  63. //
  64. // Call: AfpFSDClose
  65. //
  66. // Returns: 0 - success
  67. // non-zero returns mapped to WIN32 errors.
  68. //
  69. // Description: Closes and the AFP file system driver.
  70. //
  71. DWORD
  72. AfpFSDClose(
  73. IN HANDLE hFSD
  74. )
  75. {
  76. NTSTATUS ntStatus;
  77. ntStatus = NtClose( hFSD );
  78. if ( !NT_SUCCESS( ntStatus ) )
  79. return( RtlNtStatusToDosError( ntStatus ) );
  80. return( NO_ERROR );
  81. }
  82. //**
  83. //
  84. // Call: AfpFSDUnload
  85. //
  86. // Returns: 0 - success
  87. // non-zero returns mapped to WIN32 errors.
  88. //
  89. // Description: Unloads the AFP file system driver.
  90. //
  91. DWORD
  92. AfpFSDUnload(
  93. VOID
  94. )
  95. {
  96. NTSTATUS status;
  97. LPWSTR registryPathBuffer;
  98. UNICODE_STRING registryPath;
  99. registryPathBuffer = (LPWSTR)MIDL_user_allocate(
  100. sizeof(AFPSERVER_REGISTRY_KEY) );
  101. if ( registryPathBuffer == NULL )
  102. return ERROR_NOT_ENOUGH_MEMORY;
  103. wcscpy( registryPathBuffer, AFPSERVER_REGISTRY_KEY );
  104. RtlInitUnicodeString( &registryPath, registryPathBuffer );
  105. // Wait here for all the server helper threads to terminate
  106. if (AfpGlobals.nThreadCount > 0)
  107. WaitForSingleObject( AfpGlobals.heventSrvrHlprThreadTerminate, INFINITE );
  108. status = NtUnloadDriver( &registryPath );
  109. MIDL_user_free( registryPathBuffer );
  110. return( RtlNtStatusToDosError( status ));
  111. }
  112. //**
  113. //
  114. // Call: AfpFSDLoad
  115. //
  116. // Returns: 0 - success
  117. // non-zero returns mapped to WIN32 errors.
  118. //
  119. // Description: Loads the AFP file system driver.
  120. //
  121. DWORD
  122. AfpFSDLoad(
  123. VOID
  124. )
  125. {
  126. NTSTATUS status;
  127. LPWSTR registryPathBuffer;
  128. UNICODE_STRING registryPath;
  129. BOOLEAN fEnabled;
  130. registryPathBuffer = (LPWSTR)MIDL_user_allocate(
  131. sizeof(AFPSERVER_REGISTRY_KEY) );
  132. if ( registryPathBuffer == NULL )
  133. return ERROR_NOT_ENOUGH_MEMORY;
  134. status = RtlAdjustPrivilege( SE_LOAD_DRIVER_PRIVILEGE,
  135. TRUE,
  136. FALSE,
  137. &fEnabled );
  138. if ( !NT_SUCCESS( status ) ) {
  139. MIDL_user_free( registryPathBuffer );
  140. return( RtlNtStatusToDosError( status ));
  141. }
  142. wcscpy( registryPathBuffer, AFPSERVER_REGISTRY_KEY );
  143. RtlInitUnicodeString( &registryPath, registryPathBuffer );
  144. status = NtLoadDriver( &registryPath );
  145. MIDL_user_free( registryPathBuffer );
  146. if ( status == STATUS_IMAGE_ALREADY_LOADED )
  147. status = STATUS_SUCCESS;
  148. return( RtlNtStatusToDosError( status ));
  149. }
  150. //**
  151. //
  152. // Call: AfpFSDIOControl
  153. //
  154. // Returns: 0 - success
  155. // AFPERR - Macintosh specific errors.
  156. // non-zero returns mapped to WIN32 errors.
  157. //
  158. //
  159. // Description: Will ioctl the AFP FSD.
  160. // NtDeviceIoControlFile api is used to communicate with the FSD
  161. // instead of it's WIN32 counterpart because the WIN32 version
  162. // maps all return codes to WIN32 error codes. This runs into
  163. // problems when AFPERR_XXX error codes are returned.
  164. //
  165. DWORD
  166. AfpFSDIOControl(
  167. IN HANDLE hFSD,
  168. IN DWORD dwOpCode,
  169. IN PVOID pInbuf OPTIONAL,
  170. IN DWORD cbInbufLen,
  171. OUT PVOID pOutbuf OPTIONAL,
  172. IN DWORD cbOutbufLen,
  173. OUT LPDWORD lpcbBytesTransferred
  174. )
  175. {
  176. NTSTATUS ntRetCode;
  177. IO_STATUS_BLOCK IOStatus;
  178. ntRetCode = NtDeviceIoControlFile( hFSD,
  179. NULL,
  180. NULL,
  181. NULL,
  182. &IOStatus,
  183. dwOpCode,
  184. pInbuf,
  185. cbInbufLen,
  186. pOutbuf,
  187. cbOutbufLen );
  188. *lpcbBytesTransferred = (DWORD)(IOStatus.Information);
  189. if ( ntRetCode ) {
  190. // If it is not an AFPERR_* then map it
  191. //
  192. if ( ( ntRetCode < AFPERR_BASE ) && ( ntRetCode >= AFPERR_MIN ) )
  193. return( ntRetCode );
  194. else
  195. return( RtlNtStatusToDosError( ntRetCode ) );
  196. }
  197. else
  198. return( NO_ERROR );
  199. }
  200. //**
  201. //
  202. // Call:
  203. //
  204. // Returns:
  205. //
  206. // Description:
  207. //
  208. DWORD
  209. AfpCreateServerHelperThread(
  210. BOOL fIsFirstThread
  211. )
  212. {
  213. DWORD dwId;
  214. if ( CreateThread( NULL,
  215. 0,
  216. AfpServerHelper,
  217. (LPVOID)((ULONG_PTR)fIsFirstThread),
  218. 0,
  219. &dwId ) == NULL )
  220. return( GetLastError() );
  221. else
  222. return( NO_ERROR );
  223. }
  224. //**
  225. //
  226. // Call:
  227. //
  228. // Returns:
  229. //
  230. // Description:
  231. //
  232. VOID
  233. AfpTerminateCurrentThread(
  234. VOID
  235. )
  236. {
  237. TerminateThread( GetCurrentThread(), NO_ERROR );
  238. }