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.

278 lines
9.2 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. mprbase.hxx
  5. Abstract:
  6. Contains class definitions for base classes that implement common code
  7. for Multi-Provider Router operations, namely:
  8. CMprOperation
  9. CRoutedOperation
  10. Author:
  11. Anirudh Sahni (anirudhs) 11-Oct-1995
  12. Environment:
  13. User Mode -Win32
  14. Revision History:
  15. 11-Oct-1995 AnirudhS
  16. Created.
  17. --*/
  18. #ifndef _MPRBASE_HXX_
  19. #define _MPRBASE_HXX_
  20. //=======================
  21. // MACROS
  22. //=======================
  23. // Macro used to access PROVIDER class member functions in a generic
  24. // fashion without creating an array of functions
  25. #define PROVIDERFUNC(x) ((FARPROC PROVIDER::*) (&PROVIDER::x))
  26. // Macro for use in declaring subclasses of CRoutedOperation
  27. #define DECLARE_CROUTED \
  28. \
  29. protected: \
  30. \
  31. DWORD ValidateRoutedParameters( \
  32. LPCWSTR * ppProviderName, \
  33. LPCWSTR * ppRemoteName, \
  34. LPCWSTR * ppLocalName \
  35. ); \
  36. \
  37. DWORD TestProvider( \
  38. const PROVIDER *pProvider \
  39. );
  40. // "Debug-only parameter" macro
  41. #if DBG == 1
  42. #define DBGPARM(x) x,
  43. #else
  44. #define DBGPARM(x)
  45. #endif
  46. //=======================
  47. // CONSTANTS
  48. //=======================
  49. // Number of recently used net paths for CPathCache to remember
  50. #define PATH_CACHE_SIZE 4
  51. // Possible algorithms for routing among providers
  52. enum ROUTING_ALGORITHM
  53. {
  54. ROUTE_LAZY,
  55. ROUTE_AGGRESSIVE
  56. };
  57. //+-------------------------------------------------------------------------
  58. //
  59. // Class: CMprOperation
  60. //
  61. // Purpose: An MPR operation is an API in which the MPR needs to be
  62. // initialized, parameters need to be validated, operation-
  63. // specific processing needs to be performed, and the result
  64. // needs to be saved by SetLastError.
  65. //
  66. // CMprOperation::Perform provides this common outline.
  67. // Each MPR API can be implemented by providing a derived class.
  68. // The derived class must fill in the API-specific processing
  69. // by supplying the ValidateParameters and GetResult methods.
  70. //
  71. // Interface: Constructor - API can only construct an instance of a derived
  72. // class, passing it the API parameters.
  73. // Perform - API calls this to make the operation happen.
  74. // ValidateParameters - In this method, the derived class does
  75. // any parameter validation that could cause an exception.
  76. // GetResult - In this method, the derived class does operation-
  77. // specific processing.
  78. //
  79. // History: 11-Oct-95 AnirudhS Created.
  80. //
  81. // Notes:
  82. //
  83. //--------------------------------------------------------------------------
  84. class CMprOperation
  85. {
  86. public:
  87. virtual DWORD Perform();
  88. #if DBG == 1
  89. LPCSTR OpName()
  90. { return _OpName; }
  91. #endif
  92. protected:
  93. #if DBG == 1
  94. CMprOperation(LPCSTR OpName) :
  95. _OpName(OpName)
  96. { }
  97. #else
  98. CMprOperation()
  99. { }
  100. #endif
  101. virtual DWORD ValidateParameters() = 0;
  102. virtual DWORD GetResult() = 0;
  103. #if DBG == 1
  104. private:
  105. LPCSTR _OpName; // API name to print in debug messages
  106. #endif
  107. };
  108. //+-------------------------------------------------------------------------
  109. //
  110. // Class: CRoutedOperation
  111. //
  112. // Purpose: A Routed Operation is an MPR operation which needs to be
  113. // routed to the provider responsible, usually by either
  114. // calling a provider that is named by the API caller, or
  115. // polling all the providers and determining the right one
  116. // based on the errors returned.
  117. // This is a common type of MPR operation, so this subclass of
  118. // CMprOperation, CRoutedOperation, is defined to hold the
  119. // common code. A derived class is required for each routed
  120. // operation.
  121. //
  122. // Parameter validation for a routed operation usually includes
  123. // validating the name of a specific NP that may have been
  124. // passed in by the caller of the WNet API, so CRoutedOperation
  125. // ::ValidateParameters does this.
  126. // CRoutedOperation::GetResult provides the logic for polling
  127. // the providers and picking the best error. This may still be
  128. // overridden if it does not exactly meet a particular
  129. // operation's needs.
  130. //
  131. // Derived classes need to provide the methods
  132. // ValidateRoutedParameters and TestProvider.
  133. //
  134. // Interface:
  135. //
  136. // History: 11-Oct-95 AnirudhS Created.
  137. //
  138. // Notes:
  139. //
  140. //--------------------------------------------------------------------------
  141. class CRoutedOperation : public CMprOperation
  142. {
  143. public:
  144. DWORD Perform(BOOL fCheckProviders);
  145. // CODEWORK: This should become private once all APIs use CRoutedOperation
  146. static DWORD FindCallOrder(
  147. const UNICODE_STRING *NameInfo,
  148. LPPROVIDER ProviderArray[],
  149. LPDWORD ProviderArrayCount,
  150. DWORD InitClass
  151. );
  152. static void ConstructCache()
  153. { _PathCache.Construct(); }
  154. static void DestroyCache()
  155. { _PathCache.Destroy(); }
  156. protected:
  157. CRoutedOperation(
  158. DBGPARM(LPCSTR OpName)
  159. FARPROC PROVIDER::* pProviderFunction = NULL,
  160. ROUTING_ALGORITHM Routing = ROUTE_LAZY
  161. ) :
  162. DBGPARM(CMprOperation(OpName))
  163. _pProviderFunction (pProviderFunction),
  164. _AggressiveRouting (Routing == ROUTE_AGGRESSIVE),
  165. _pSpecifiedProvider(NULL),
  166. _LastProvider (NULL),
  167. _uDriveType (DRIVE_REMOTE)
  168. { }
  169. //
  170. // Helper functions for child classes
  171. //
  172. PROVIDER * LastProvider() const
  173. { return _LastProvider; }
  174. //
  175. // Implementations of CMprOperation functions
  176. //
  177. DWORD ValidateParameters();
  178. DWORD GetResult();
  179. //
  180. // Virtual functions that child classes should supply
  181. //
  182. virtual DWORD ValidateRoutedParameters(
  183. LPCWSTR *ppProviderName,
  184. LPCWSTR *ppRemoteName,
  185. LPCWSTR *ppLocalName
  186. ) = 0;
  187. virtual DWORD TestProvider(
  188. const PROVIDER * pProvider
  189. ) = 0;
  190. private:
  191. FARPROC PROVIDER::*
  192. _pProviderFunction; // Required provider function, if any
  193. BOOL _AggressiveRouting; // Whether to continue on "other" errors
  194. PROVIDER * _pSpecifiedProvider; // Provider specified in API parameters
  195. UNICODE_STRING _RemoteName; // Remote name specified in API parameters
  196. PROVIDER * _LastProvider; // On a success return from GetResult,
  197. // is the provider that responded
  198. UINT _uDriveType; // Optimization -- if the localname is
  199. // not a remote drive, some APIs can
  200. // fail w/o loading the provider DLLs
  201. //
  202. // Cache of providers for the last few net paths accessed through WNet APIs
  203. //
  204. class CPathCache
  205. {
  206. public:
  207. void Construct();
  208. void Destroy();
  209. void AddEntry(const UNICODE_STRING * Path, LPPROVIDER Provider);
  210. LPPROVIDER FindEntry(const UNICODE_STRING * Path);
  211. private:
  212. // The cache is a doubly linked list of UNICODE_STRINGs and LPPROVIDERs.
  213. // The string buffers are allocated on the heap but the the list
  214. // entries are allocated statically.
  215. struct CacheEntry
  216. {
  217. LIST_ENTRY Links;
  218. UNICODE_STRING Path;
  219. LPPROVIDER Provider;
  220. };
  221. CRITICAL_SECTION _Lock;
  222. CacheEntry _RecentPaths[PATH_CACHE_SIZE];
  223. LIST_ENTRY _ListHead;
  224. DWORD _NumFree; // _RecentPaths[0] thru [_NumFree-1] are unused
  225. };
  226. static CPathCache _PathCache;
  227. };
  228. #endif // _MPRBASE_HXX_