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.

312 lines
12 KiB

  1. /*++
  2. Copyright (c) 1991-92 Microsoft Corporation
  3. Module Name:
  4. SvcInst.c
  5. Abstract:
  6. This file contains the RpcXlate code to handle the Service APIs.
  7. Author:
  8. John Rogers (JohnRo) 13-Sep-1991
  9. Environment:
  10. Portable to any flat, 32-bit environment. (Uses Win32 typedefs.)
  11. Requires ANSI C extensions: slash-slash comments, long external names.
  12. Revision History:
  13. 13-Sep-1991 JohnRo
  14. Created.
  15. 16-Sep-1991 JohnRo
  16. Made changes suggested by PC-LINT.
  17. 24-Sep-1991 JohnRo
  18. Fixed bug when ArgC is 0. Also changed to pass data descs to
  19. RxRemoteApi. We also have to do the structure conversion here.
  20. 21-Nov-1991 JohnRo
  21. Removed NT dependencies to reduce recompiles.
  22. 18-Dec-1991 JohnRo
  23. Improved UNICODE handling.
  24. 07-Feb-1992 JohnRo
  25. Use NetApiBufferAllocate() instead of private version.
  26. 27-Oct-1992 JohnRo
  27. Fixed problem setting up string area pointer for RapConvertSingleEntry.
  28. Use PREFIX_ equates.
  29. --*/
  30. // These must be included first:
  31. #include <windef.h> // IN, DWORD, etc.
  32. #include <lmcons.h> // DEVLEN, NET_API_STATUS, etc.
  33. // These may be included in any order:
  34. #include <apinums.h> // API_ equates.
  35. #include <lmapibuf.h> // NetApiBufferAllocate(), NetApiBufferFree().
  36. #include <lmerr.h> // ERROR_ and NERR_ equates.
  37. #include <lmsvc.h>
  38. #include <rxp.h> // RxpFatalErrorCode().
  39. #include <netdebug.h> // NetpKdPrint(()), FORMAT_ equates.
  40. #include <netlib.h> // NetpPointerPlusSomeBytes().
  41. #include <prefix.h> // PREFIX_ equates.
  42. #include <rap.h> // LPDESC, RapConvertSingleEntry().
  43. #include <remdef.h> // REM16_, REM32_, REMSmb_ equates.
  44. #include <rx.h> // RxRemoteApi().
  45. #include <rxpdebug.h> // IF_DEBUG().
  46. #include <rxsvc.h> // My prototype.
  47. #include <strucinf.h> // NetpServiceStructureInfo().
  48. #include <tstring.h> // STRCPY(), STRLEN().
  49. NET_API_STATUS
  50. RxNetServiceInstall (
  51. IN LPTSTR UncServerName,
  52. IN LPTSTR Service,
  53. IN DWORD ArgC,
  54. IN LPTSTR ArgV[],
  55. OUT LPBYTE *BufPtr
  56. )
  57. {
  58. NET_API_STATUS ApiStatus;
  59. DWORD ArgIndex; // Index into array of strings.
  60. LPSTR CmdArgs; // ptr to alloc'ed ASCII list of strings.
  61. DWORD CmdArgsIndex; // Char index into CmdArgs.
  62. DWORD CmdArgsLen = 0; // Number of chars in CmdArgs (incl null).
  63. const DWORD Level = 2; // Implied by this API.
  64. LPVOID OldInfo; // Info structure in downlevel format.
  65. DWORD OldTotalSize; // Size of struct in old (downlevel) format.
  66. NET_API_STATUS TempStatus;
  67. LPSERVICE_INFO_2 serviceInfo2;
  68. NetpAssert(UncServerName != NULL);
  69. NetpAssert(*UncServerName != '\0');
  70. //
  71. // Compute how much memory we'll need for single CmdArgs array.
  72. //
  73. for (ArgIndex = 0; ArgIndex < ArgC; ++ArgIndex) {
  74. #if defined(UNICODE) // RxNetServiceInstall ()
  75. CmdArgsLen += NetpUnicodeToDBCSLen(ArgV[ArgIndex]) + 1; // string and null.
  76. #else
  77. CmdArgsLen += STRLEN(ArgV[ArgIndex]) + 1; // string and null.
  78. #endif // defined(UNICODE)
  79. }
  80. ++CmdArgsLen; // include a null char at end of array.
  81. //
  82. // Allocate the array. This is in ASCII, so we don't need to
  83. // add sizeof(some_char_type).
  84. //
  85. TempStatus = NetApiBufferAllocate( CmdArgsLen, (LPVOID *) & CmdArgs );
  86. if (TempStatus != NERR_Success) {
  87. return (TempStatus);
  88. }
  89. NetpAssert(CmdArgs != NULL);
  90. //
  91. // Build ASCII version of CmdArgs.
  92. //
  93. CmdArgsIndex = 0; // start
  94. for (ArgIndex=0; ArgIndex<ArgC; ++ArgIndex) {
  95. NetpAssert( ArgV[ArgIndex] != NULL );
  96. #if defined(UNICODE) // RxNetServiceInstall ()
  97. NetpCopyWStrToStrDBCS(
  98. & CmdArgs[CmdArgsIndex], // dest
  99. ArgV[ArgIndex] ); // src
  100. CmdArgsIndex += strlen(&CmdArgs[CmdArgsIndex])+1; //str and null
  101. #else
  102. NetpCopyTStrToStr(
  103. & CmdArgs[CmdArgsIndex], // dest
  104. ArgV[ArgIndex]); // src
  105. CmdArgsIndex += STRLEN(ArgV[ArgIndex]) + 1; // str and null.
  106. #endif // defined(UNICODE)
  107. }
  108. CmdArgs[CmdArgsIndex] = '\0'; // null char to end list.
  109. IF_DEBUG(SERVICE) {
  110. NetpKdPrint(( PREFIX_NETAPI
  111. "RxNetServiceInstall: cmd args (partial):\n" ));
  112. NetpDbgHexDump( (LPBYTE) (LPVOID) CmdArgs,
  113. NetpDbgReasonable(CmdArgsLen) );
  114. }
  115. //
  116. // Find out about the downlevel version of this data structure.
  117. // Allocate space for it. (See note below as to why we have to do this
  118. // here rather than in RxRemoteApi.)
  119. //
  120. TempStatus = NetpServiceStructureInfo (
  121. Level,
  122. PARMNUM_ALL, // want entire structure
  123. FALSE, // Want downlevel size.
  124. NULL, // don't need DataDesc16 here
  125. NULL, // don't need DataDesc32 here
  126. NULL, // don't need DataDescSmb here
  127. & OldTotalSize, // max size (downlevel version)
  128. NULL, // don't care about fixed size
  129. NULL); // don't care about string size
  130. NetpAssert(TempStatus == NERR_Success);
  131. TempStatus = NetApiBufferAllocate( OldTotalSize, (LPVOID *) & OldInfo );
  132. if (TempStatus != NERR_Success) {
  133. (void) NetApiBufferFree(CmdArgs);
  134. return (TempStatus);
  135. }
  136. //
  137. // Remote the API.
  138. //
  139. // Note that this is strange because there should be descriptors for two
  140. // things: the cmd buffer we're sending, and the structure we're expecting
  141. // back. The downlevel system is only expecting a descriptor for the
  142. // cmd args, so RxRemoteApi won't be able to convert the structure into
  143. // native format for us. So we'll have to convert it later.
  144. //
  145. // Also, the following comment (from the LM 2.x svc_inst.c) explains
  146. // why we're passing something besides the expected value for cbBuffer:
  147. //
  148. /* Now for a slightly unclean fix for an oversight in the
  149. * parameters spec'ed for this call. The command arg buf is
  150. * the variable length buffer while the outbuf is actually
  151. * a fixed length structure (no var. length ptrs) yet the
  152. * parameters to the API give only the outbuflen. In order
  153. * to transport the API remotely the outbuflen (which has
  154. * already been length verified) is used to transport the
  155. * ca_len, and will be reset to sizeof(struct service_info_2)
  156. * by a remote only entry point to the API.
  157. */
  158. ApiStatus = RxRemoteApi(
  159. API_WServiceInstall, // API number
  160. UncServerName,
  161. REMSmb_NetServiceInstall_P, // parm desc
  162. REM16_service_cmd_args, // send cmd desc, NOT DataDesc16
  163. REM16_service_cmd_args, // send cmd desc, NOT DataDesc32
  164. REMSmb_service_cmd_args, // send cmd desc, NOT DataDescSmb
  165. NULL, // no aux desc 16
  166. NULL, // no aux desc 32
  167. NULL, // no aux desc SMB
  168. 0, // flags: nothing special
  169. // rest of API's arguments, in 32-bit LM2.x format:
  170. Service,
  171. CmdArgs, // ASCII version of cmd args.
  172. OldInfo, // pbBuffer
  173. CmdArgsLen); // cbBuffer (not OldTotalSize; see
  174. // comment above).
  175. IF_DEBUG(SERVICE) {
  176. NetpKdPrint(( PREFIX_NETAPI
  177. "RxNetServiceInstall: OldInfo=" FORMAT_LPVOID ".\n",
  178. (LPVOID) OldInfo ));
  179. if (OldInfo) {
  180. NetpKdPrint(( PREFIX_NETAPI
  181. "RxNetServiceInstall: *OldInfo=" FORMAT_LPVOID ".\n",
  182. *(LPVOID *) OldInfo ));
  183. }
  184. }
  185. NetpAssert( ApiStatus != ERROR_MORE_DATA );
  186. if (ApiStatus == NERR_Success) {
  187. DWORD BytesRequired = 0; // 0 bytes used so far.
  188. LPDESC DataDesc16, DataDesc32;
  189. LPVOID NewInfo;
  190. DWORD NewTotalSize;
  191. LPBYTE StringLocation;
  192. //
  193. // Set up to do conversion to native format.
  194. //
  195. TempStatus = NetpServiceStructureInfo (
  196. Level,
  197. PARMNUM_ALL, // want entire structure
  198. TRUE, // want native size.
  199. & DataDesc16,
  200. & DataDesc32,
  201. NULL, // don't need data desc SMB
  202. & NewTotalSize, // max size (downlevel version)
  203. NULL, // don't care about fixed size
  204. NULL); // don't care about string size
  205. NetpAssert(TempStatus == NERR_Success); // Level can't be wrong.
  206. TempStatus = NetApiBufferAllocate(
  207. NewTotalSize,
  208. (LPVOID *) & NewInfo );
  209. if (TempStatus != NERR_Success) {
  210. (void) NetApiBufferFree(OldInfo);
  211. (void) NetApiBufferFree(CmdArgs);
  212. return (TempStatus);
  213. }
  214. StringLocation = (LPVOID) NetpPointerPlusSomeBytes(
  215. NewInfo, NewTotalSize );
  216. //
  217. // Convert info structure to native format.
  218. //
  219. IF_DEBUG(SERVICE) {
  220. NetpKdPrint(( PREFIX_NETAPI
  221. "RxNetServiceInstall: Unconverted info at "
  222. FORMAT_LPVOID "\n", (LPVOID) OldInfo ));
  223. NetpDbgHexDump( OldInfo, OldTotalSize );
  224. }
  225. TempStatus = RapConvertSingleEntry (
  226. OldInfo, // in structure
  227. DataDesc16, // in structure desc
  228. TRUE, // meaningless input ptrs
  229. NewInfo, // output buffer start
  230. NewInfo, // output buffer
  231. DataDesc32, // output structure desc
  232. FALSE, // don't set offsets (want ptrs)
  233. & StringLocation, // where to start strs (updated)
  234. & BytesRequired, // bytes used (will be updated)
  235. Both, // transmission mode
  236. RapToNative); // conversion mode
  237. NetpAssert( TempStatus == NERR_Success );
  238. IF_DEBUG(SERVICE) {
  239. NetpKdPrint(( PREFIX_NETAPI
  240. "RxNetServiceInstall: Converted info at "
  241. FORMAT_LPVOID "\n", (LPVOID) NewInfo ));
  242. NetpDbgHexDump( NewInfo, NewTotalSize );
  243. }
  244. NetpAssert( BytesRequired <= NewTotalSize );
  245. *BufPtr = (LPBYTE) NewInfo;
  246. if ((! RxpFatalErrorCode(ApiStatus)) && (Level == 2)) {
  247. serviceInfo2 = (LPSERVICE_INFO_2)*BufPtr;
  248. if (serviceInfo2 != NULL) {
  249. DWORD installState;
  250. serviceInfo2->svci2_display_name = serviceInfo2->svci2_name;
  251. //
  252. // if INSTALL or UNINSTALL is PENDING, then force the upper
  253. // bits to 0. This is to prevent the upper bits of the wait
  254. // hint from getting accidentally set. Downlevel should never
  255. // use more than FF for waithint.
  256. //
  257. installState = serviceInfo2->svci2_status & SERVICE_INSTALL_STATE;
  258. if ((installState == SERVICE_INSTALL_PENDING) ||
  259. (installState == SERVICE_UNINSTALL_PENDING)) {
  260. serviceInfo2->svci2_code &= SERVICE_RESRV_MASK;
  261. }
  262. }
  263. }
  264. } else {
  265. *BufPtr = NULL;
  266. }
  267. (void) NetApiBufferFree( OldInfo );
  268. //
  269. // Clean up and tell caller how things went.
  270. // (Caller must call NetApiBufferFree() for BufPtr.)
  271. //
  272. (void) NetApiBufferFree(CmdArgs);
  273. return (ApiStatus);
  274. } // RxNetServiceInstall