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.

278 lines
7.0 KiB

  1. //+----------------------------------------------------------------------------
  2. //
  3. // Copyright (C) 1992, Microsoft Corporation
  4. //
  5. // File: provider.c
  6. //
  7. // Contents: Module to initialize DFS driver providers.
  8. //
  9. // Classes:
  10. //
  11. // Functions: ProviderInit --
  12. // DfsGetProviderForDevice
  13. // DfsInsertProvider
  14. //
  15. // History: 12 Sep 1992 Milans created.
  16. // 05 Apr 1993 Milans moved into driver.
  17. //
  18. //-----------------------------------------------------------------------------
  19. #include "dfsprocs.h"
  20. #include "rpselect.h"
  21. #include "provider.h"
  22. #define MAX_ENTRY_PATH 80 // Max. length of entry path
  23. #define Dbg DEBUG_TRACE_INIT
  24. #define prov_debug_out(x, y) DfsDbgTrace(0, Dbg, x, y)
  25. #ifdef ALLOC_PRAGMA
  26. #pragma alloc_text( PAGE, ProviderInit )
  27. #pragma alloc_text( PAGE, DfsGetProviderForDevice )
  28. #pragma alloc_text( PAGE, DfsInsertProvider )
  29. #endif // ALLOC_PRAGMA
  30. //+----------------------------------------------------------------------------
  31. //
  32. // Function: ProviderInit
  33. //
  34. // Synopsis: Initializes the provider list with
  35. // - Local File service provider
  36. // - Standard remote Cairo provider
  37. // - Downlevel LanMan provider.
  38. //
  39. // Arguments: None
  40. //
  41. // Returns: STATUS_SUCCESS
  42. //
  43. //-----------------------------------------------------------------------------
  44. NTSTATUS
  45. ProviderInit(void)
  46. {
  47. NTSTATUS Status;
  48. UNICODE_STRING ustrProviderName;
  49. //
  50. // Initialize the Dfs aware SMB provider
  51. //
  52. RtlInitUnicodeString(&ustrProviderName, DD_NFS_DEVICE_NAME_U);
  53. Status = DfsInsertProvider(
  54. &ustrProviderName,
  55. PROV_DFS_RDR,
  56. PROV_ID_DFS_RDR);
  57. if (!NT_SUCCESS(Status))
  58. return(Status);
  59. RtlInitUnicodeString(&ustrProviderName, DD_MUP_DEVICE_NAME);
  60. Status = DfsInsertProvider(
  61. &ustrProviderName,
  62. PROV_STRIP_PREFIX,
  63. PROV_ID_MUP_RDR);
  64. return( Status );
  65. }
  66. //+----------------------------------------------------------------------------
  67. //
  68. // Function: DfsGetProviderForDevice
  69. //
  70. // Synopsis: Retrieves a provider definition given a Device Name. If the
  71. // provider definition does not exist, a new one is created and
  72. // returned.
  73. //
  74. // This routine is meant for use in handling a STATUS_REPARSE
  75. // returned by the MUP. Since only downlevel requests are sent
  76. // to the MUP, this routine will always return a provider def
  77. // that is marked as downlevel (ie, Capability has the
  78. // PROV_STRIP_PREFIX bit set).
  79. //
  80. // Arguments: [DeviceName] -- Name of Device to look for.
  81. //
  82. // [Provider] -- On successful return, contains pointer to
  83. // PROVIDER_DEF with given DeviceName.
  84. //
  85. // Returns: [STATUS_SUCCESS] -- Provider returned.
  86. //
  87. // [STATUS_INSUFFICIENT_RESOURCES] -- Out of memory condition.
  88. //
  89. // [STATUS_FS_DRIVER_REQUIRED] -- Don't have appropriate
  90. // provider.
  91. //
  92. //-----------------------------------------------------------------------------
  93. NTSTATUS
  94. DfsGetProviderForDevice(
  95. PUNICODE_STRING DeviceName,
  96. PPROVIDER_DEF *Provider)
  97. {
  98. NTSTATUS status;
  99. int i;
  100. ExAcquireResourceExclusiveLite( &DfsData.Resource, TRUE );
  101. *Provider = NULL;
  102. for (i = 0; i < DfsData.cProvider && *Provider == NULL; i++) {
  103. if ((DfsData.pProvider[i].DeviceName.Length == DeviceName->Length) &&
  104. (DfsData.pProvider[i].fProvCapability & PROV_STRIP_PREFIX) != 0) {
  105. if (RtlEqualUnicodeString(
  106. &DfsData.pProvider[i].DeviceName,
  107. DeviceName, TRUE)) {
  108. *Provider = &DfsData.pProvider[i];
  109. status = STATUS_SUCCESS;
  110. break;
  111. }
  112. }
  113. }
  114. if (*Provider == NULL) {
  115. //
  116. // Attempt to create a new provider def
  117. //
  118. UNICODE_STRING ProviderName;
  119. ProviderName.Length = DeviceName->Length;
  120. ProviderName.MaximumLength = ProviderName.Length + sizeof(WCHAR);
  121. ProviderName.Buffer = (PWCHAR) ExAllocatePoolWithTag(
  122. PagedPool,
  123. ProviderName.MaximumLength,
  124. ' puM');
  125. if (ProviderName.Buffer != NULL) {
  126. RtlZeroMemory(
  127. ProviderName.Buffer,
  128. ProviderName.MaximumLength);
  129. RtlMoveMemory(
  130. ProviderName.Buffer,
  131. DeviceName->Buffer,
  132. ProviderName.Length);
  133. status = DfsInsertProvider(
  134. &ProviderName,
  135. PROV_STRIP_PREFIX,
  136. i);
  137. if (status == STATUS_SUCCESS) {
  138. *Provider = &DfsData.pProvider[i];
  139. } else {
  140. ExFreePool( ProviderName.Buffer );
  141. }
  142. } else {
  143. status = STATUS_INSUFFICIENT_RESOURCES;
  144. }
  145. }
  146. ExReleaseResourceLite( &DfsData.Resource );
  147. if (*Provider != NULL && (*Provider)->FileObject == NULL) {
  148. //
  149. // We found (or created) a provider definition that is
  150. //
  151. *Provider = ReplLookupProvider( i );
  152. if (*Provider == NULL)
  153. status = STATUS_FS_DRIVER_REQUIRED;
  154. }
  155. return( status );
  156. }
  157. //+----------------------------------------------------------------------------
  158. //
  159. // Function: DfsInsertProvider
  160. //
  161. // Synopsis: Given a provider name, id, and capability, will add a new or
  162. // overwrite an existing provider definition.
  163. //
  164. // Arguments:
  165. //
  166. // Returns:
  167. //
  168. //-----------------------------------------------------------------------------
  169. NTSTATUS DfsInsertProvider(
  170. IN PUNICODE_STRING ProviderName,
  171. IN ULONG fProvCapability,
  172. IN ULONG eProviderId)
  173. {
  174. PPROVIDER_DEF pProv = DfsData.pProvider;
  175. int iProv;
  176. //
  177. // Find a free provider structure, or overwrite an existing one.
  178. //
  179. for (iProv = 0; iProv < DfsData.cProvider; iProv++, pProv++) {
  180. if (pProv->eProviderId == eProviderId)
  181. break;
  182. }
  183. if (iProv >= DfsData.maxProvider) {
  184. ASSERT(iProv >= DfsData.maxProvider && "Out of provider structs");
  185. return(STATUS_INSUFFICIENT_RESOURCES);
  186. }
  187. if (iProv < DfsData.cProvider) {
  188. //
  189. // Decrement reference counts on saved objects
  190. //
  191. if (pProv->FileObject)
  192. ObDereferenceObject(pProv->FileObject);
  193. if (pProv->DeviceObject)
  194. ObDereferenceObject(pProv->DeviceObject);
  195. if (pProv->DeviceName.Buffer)
  196. ExFreePool(pProv->DeviceName.Buffer);
  197. }
  198. pProv->FileObject = NULL;
  199. pProv->DeviceObject = NULL;
  200. pProv->eProviderId = (USHORT) eProviderId;
  201. pProv->fProvCapability = (USHORT) fProvCapability;
  202. pProv->DeviceName = *ProviderName;
  203. if (iProv == DfsData.cProvider) {
  204. DfsData.cProvider++;
  205. }
  206. return(STATUS_SUCCESS);
  207. }