/*++ Copyright (c) 1991-92 Microsoft Corporation Module Name: SvcInst.c Abstract: This file contains the RpcXlate code to handle the Service APIs. Author: John Rogers (JohnRo) 13-Sep-1991 Environment: Portable to any flat, 32-bit environment. (Uses Win32 typedefs.) Requires ANSI C extensions: slash-slash comments, long external names. Revision History: 13-Sep-1991 JohnRo Created. 16-Sep-1991 JohnRo Made changes suggested by PC-LINT. 24-Sep-1991 JohnRo Fixed bug when ArgC is 0. Also changed to pass data descs to RxRemoteApi. We also have to do the structure conversion here. 21-Nov-1991 JohnRo Removed NT dependencies to reduce recompiles. 18-Dec-1991 JohnRo Improved UNICODE handling. 07-Feb-1992 JohnRo Use NetApiBufferAllocate() instead of private version. 27-Oct-1992 JohnRo Fixed problem setting up string area pointer for RapConvertSingleEntry. Use PREFIX_ equates. --*/ // These must be included first: #include // IN, DWORD, etc. #include // DEVLEN, NET_API_STATUS, etc. // These may be included in any order: #include // API_ equates. #include // NetApiBufferAllocate(), NetApiBufferFree(). #include // ERROR_ and NERR_ equates. #include #include // RxpFatalErrorCode(). #include // NetpKdPrint(()), FORMAT_ equates. #include // NetpPointerPlusSomeBytes(). #include // PREFIX_ equates. #include // LPDESC, RapConvertSingleEntry(). #include // REM16_, REM32_, REMSmb_ equates. #include // RxRemoteApi(). #include // IF_DEBUG(). #include // My prototype. #include // NetpServiceStructureInfo(). #include // STRCPY(), STRLEN(). NET_API_STATUS RxNetServiceInstall ( IN LPTSTR UncServerName, IN LPTSTR Service, IN DWORD ArgC, IN LPTSTR ArgV[], OUT LPBYTE *BufPtr ) { NET_API_STATUS ApiStatus; DWORD ArgIndex; // Index into array of strings. LPSTR CmdArgs; // ptr to alloc'ed ASCII list of strings. DWORD CmdArgsIndex; // Char index into CmdArgs. DWORD CmdArgsLen = 0; // Number of chars in CmdArgs (incl null). const DWORD Level = 2; // Implied by this API. LPVOID OldInfo; // Info structure in downlevel format. DWORD OldTotalSize; // Size of struct in old (downlevel) format. NET_API_STATUS TempStatus; LPSERVICE_INFO_2 serviceInfo2; NetpAssert(UncServerName != NULL); NetpAssert(*UncServerName != '\0'); // // Compute how much memory we'll need for single CmdArgs array. // for (ArgIndex = 0; ArgIndex < ArgC; ++ArgIndex) { #if defined(UNICODE) // RxNetServiceInstall () CmdArgsLen += NetpUnicodeToDBCSLen(ArgV[ArgIndex]) + 1; // string and null. #else CmdArgsLen += STRLEN(ArgV[ArgIndex]) + 1; // string and null. #endif // defined(UNICODE) } ++CmdArgsLen; // include a null char at end of array. // // Allocate the array. This is in ASCII, so we don't need to // add sizeof(some_char_type). // TempStatus = NetApiBufferAllocate( CmdArgsLen, (LPVOID *) & CmdArgs ); if (TempStatus != NERR_Success) { return (TempStatus); } NetpAssert(CmdArgs != NULL); // // Build ASCII version of CmdArgs. // CmdArgsIndex = 0; // start for (ArgIndex=0; ArgIndexsvci2_display_name = serviceInfo2->svci2_name; // // if INSTALL or UNINSTALL is PENDING, then force the upper // bits to 0. This is to prevent the upper bits of the wait // hint from getting accidentally set. Downlevel should never // use more than FF for waithint. // installState = serviceInfo2->svci2_status & SERVICE_INSTALL_STATE; if ((installState == SERVICE_INSTALL_PENDING) || (installState == SERVICE_UNINSTALL_PENDING)) { serviceInfo2->svci2_code &= SERVICE_RESRV_MASK; } } } } else { *BufPtr = NULL; } (void) NetApiBufferFree( OldInfo ); // // Clean up and tell caller how things went. // (Caller must call NetApiBufferFree() for BufPtr.) // (void) NetApiBufferFree(CmdArgs); return (ApiStatus); } // RxNetServiceInstall