/*++ Copyright (c) 1995 Microsoft Corporation Module Name: llsrpc.c Abstract: Client side RPC wrappers for License Logging Service. Author: Arthur Hanson (arth) 30-Jan-1995 Revision History: Jeff Parham (jeffparh) 04-Dec-1995 o Forced include of LLS API prototypes, exposing an incorrect prototype in LLSAPI.H. o Fixed case where an LSA access denied was interpreted as implying the server had no DC, rather than properly bubbling the access denied back to the caller (of LlsConnectEnterprise()). This plugs a security hole wherein a non-admin user with the ability to read the System registry key would be allowed to administer domain licenses through License Manager. (Bug #11441.) o Added functions to support extended LLSRPC API. o Removed replication dependency on no further LlsConnect()'s being made until replication was completed. o Installed lock around llsrpc_handle global binding variable. Required addition of DllMain() function. o Added LLSRPC capabilities detection. Upon connection, the client requests the server's capabilities (an RPC call which itself will fail when connected to a 3.51 server). The capabilities set is an arbitrary bit field, but individual bits are normally defined to indicate that a specific feature has been implemented at the server. o Added szServerName filed to LOCAL_HANDLE to remember the name of the machine to which we're connected. --*/ #include #include #include #include #include #include #include #include #include #include "debug.h" #include "llsapi.h" #include "llsrpc_c.h" #include "lsapi_c.h" // #define API_TRACE typedef struct _GENERIC_INFO_CONTAINER { DWORD EntriesRead; LPBYTE Buffer; } GENERIC_INFO_CONTAINER, *PGENERIC_INFO_CONTAINER, *LPGENERIC_INFO_CONTAINER ; typedef struct _GENERIC_ENUM_STRUCT { DWORD Level; PGENERIC_INFO_CONTAINER Container; } GENERIC_ENUM_STRUCT, *PGENERIC_ENUM_STRUCT, *LPGENERIC_ENUM_STRUCT ; typedef struct _LOCAL_HANDLE { TCHAR szServerName[ 3 + MAX_PATH ]; LPTSTR pszStringBinding; handle_t llsrpc_handle; LLS_HANDLE Handle; BYTE Capabilities[ ( LLS_CAPABILITY_MAX + 7 ) / 8 ]; } LOCAL_HANDLE, *PLOCAL_HANDLE; LPTSTR pszStringBinding = NULL; RTL_CRITICAL_SECTION g_RpcHandleLock; ///////////////////////////////////////////////////////////////////////// BOOL APIENTRY DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved ) /*++ Routine Description: Standard DLL entry point. Arguments: hInstance (HINSTANCE) dwReason (DWORD) lpReserved (LPVOID) Return Value: TRUE if successful. --*/ { NTSTATUS nt = STATUS_SUCCESS; switch (dwReason) { case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(hInstance); nt = RtlInitializeCriticalSection( &g_RpcHandleLock ); break; case DLL_PROCESS_DETACH: nt = RtlDeleteCriticalSection( &g_RpcHandleLock ); break; } return NT_SUCCESS( nt ); } ///////////////////////////////////////////////////////////////////////// NTSTATUS NTDomainGet( LPTSTR ServerName, LPTSTR Domain ) /*++ Routine Description: Arguments: Return Value: None. --*/ { TCHAR Serv[MAX_PATH + 3]; UNICODE_STRING us; NTSTATUS ret; OBJECT_ATTRIBUTES oa; ACCESS_MASK am; SECURITY_QUALITY_OF_SERVICE qos; LSA_HANDLE hLSA; PPOLICY_PRIMARY_DOMAIN_INFO pvBuffer; lstrcpy(Domain, TEXT("")); // only need read access // //am = POLICY_READ | POLICY_VIEW_LOCAL_INFORMATION; am = MAXIMUM_ALLOWED; // set up quality of service qos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE); qos.ImpersonationLevel = SecurityImpersonation; qos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING; qos.EffectiveOnly = FALSE; // Macro sets everything except security field InitializeObjectAttributes( &oa, NULL, 0L, NULL, NULL ); oa.SecurityQualityOfService = &qos; if ( (ServerName == NULL) || (ServerName[0] == TEXT('\0')) ) ret = LsaOpenPolicy(NULL, &oa, am, &hLSA); else { if (ServerName[0] == TEXT('\\')) lstrcpy(Serv, ServerName); else wsprintf(Serv, TEXT("\\\\%s"), ServerName); // Set up unicode string structure us.Length = (USHORT)(lstrlen(Serv) * sizeof(TCHAR)); us.MaximumLength = us.Length + sizeof(TCHAR); us.Buffer = Serv; ret = LsaOpenPolicy(&us, &oa, am, &hLSA); } if (!ret) { ret = LsaQueryInformationPolicy(hLSA, PolicyPrimaryDomainInformation, (PVOID *) &pvBuffer); LsaClose(hLSA); if ((!ret) && (pvBuffer != NULL) && (pvBuffer->Sid != NULL)) { lstrcpy(Domain, pvBuffer->Name.Buffer); LsaFreeMemory((PVOID) pvBuffer); } else if (!ret) ret = STATUS_UNSUCCESSFUL; } return ret; } // NTDomainGet ///////////////////////////////////////////////////////////////////////// NTSTATUS EnterpriseServerGet( LPTSTR ServerName, LPTSTR pEnterpriseServer ) /*++ Routine Description: Arguments: Return Value: None. --*/ { HKEY hKey = NULL; HKEY hKey2 = NULL; BOOL Enterprise = FALSE; BOOL bIsNetBIOSName = TRUE; DWORD dwType, dwSize; TCHAR RegKeyText[512]; NTSTATUS Status; DWORD UseEnterprise; TCHAR EnterpriseServer[MAX_PATH + 3] = TEXT(""); LPTSTR pName = ServerName; Status = RegConnectRegistry(ServerName, HKEY_LOCAL_MACHINE, &hKey); if (Status == ERROR_SUCCESS) { // // Create registry key-name we are looking for // lstrcpy(RegKeyText, TEXT("System\\CurrentControlSet\\Services\\LicenseService\\Parameters")); if ((Status = RegOpenKeyEx(hKey, RegKeyText, 0, KEY_READ, &hKey2)) == ERROR_SUCCESS) { dwSize = sizeof(UseEnterprise); Status = RegQueryValueEx(hKey2, TEXT("UseEnterprise"), NULL, &dwType, (LPBYTE) &UseEnterprise, &dwSize); if ((Status == ERROR_SUCCESS) && (UseEnterprise == 1)) { // // ** NEW - NT 5.0 ** // // NB : This is temporary code! The proper way to do this is to // consult the license settings object in the site in which // the server resides. // // Read the SiteServer value first, if available, to get the site // server's DNS name. If this fails, default to EnterpriseServer. // dwSize = sizeof(EnterpriseServer); Status = RegQueryValueEx(hKey2, TEXT("SiteServer"), NULL, &dwType, (LPBYTE) &EnterpriseServer, &dwSize); if (Status == ERROR_SUCCESS && EnterpriseServer[0]) { bIsNetBIOSName = FALSE; } else { dwSize = sizeof(EnterpriseServer); Status = RegQueryValueEx(hKey2, TEXT("EnterpriseServer"), NULL, &dwType, (LPBYTE) &EnterpriseServer, &dwSize); } if (Status == ERROR_SUCCESS) { pName = EnterpriseServer; } } RegCloseKey(hKey2); } RegCloseKey(hKey); } if (bIsNetBIOSName && *pName != TEXT('\\')) { lstrcpy(pEnterpriseServer, TEXT("\\\\")); lstrcat(pEnterpriseServer, pName); } else lstrcpy(pEnterpriseServer, pName); return STATUS_SUCCESS; } // EnterpriseServerGet ///////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsEnterpriseServerFindW( LPTSTR Focus, DWORD Level, LPBYTE *BufPtr ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; LPTSTR pFocus; BOOL Domain = TRUE; LPTSTR pszUuid = NULL; LPTSTR pszProtocolSequence = NULL; LPTSTR pszNetworkAddress = NULL; LPTSTR pszEndpoint = NULL; LPTSTR pszOptions = NULL; TCHAR EnterpriseServer[MAX_PATH + 4]; TCHAR pDomain[MAX_PATH + 4]; DWORD uRet; PDOMAIN_CONTROLLER_INFO pbBuffer = NULL; PLLS_CONNECT_INFO_0 pConnectInfo; ULONG Size; DSROLE_PRIMARY_DOMAIN_INFO_BASIC *pDomainInfo = NULL; BOOL fInWorkgroup = TRUE; if (Level != 0) return STATUS_INVALID_LEVEL; pDomain[0] = 0; EnterpriseServer[0] = 0; // // Figure out if doing domain or server // pFocus = Focus; if (pFocus !=NULL) while ((*pFocus != TEXT('\0')) && (*pFocus == TEXT('\\'))) { Domain = FALSE; pFocus++; } uRet = DsRoleGetPrimaryDomainInformation((!Domain) ? Focus : NULL, DsRolePrimaryDomainInfoBasic, (PBYTE *) &pDomainInfo); if ((uRet == NO_ERROR) && (pDomainInfo != NULL) && (pDomainInfo->MachineRole != DsRole_RoleStandaloneWorkstation) && (pDomainInfo->MachineRole != DsRole_RoleStandaloneServer)) { fInWorkgroup = FALSE; } if ((uRet == NO_ERROR) && (pDomainInfo != NULL)) { DsRoleFreeMemory(pDomainInfo); } if (!fInWorkgroup) { // // If we got a domain find the DC of it, else find DC of server // if (!Domain) { uRet = DsGetDcName(Focus, NULL, NULL, NULL, DS_BACKGROUND_ONLY, &pbBuffer); } else { // // Get the DC name of wherever we are going // if ((pFocus == NULL) || (*pFocus == TEXT('\0'))) uRet = DsGetDcName(NULL, NULL, NULL, NULL, DS_BACKGROUND_ONLY, &pbBuffer); else uRet = DsGetDcName(NULL, pFocus, NULL, NULL, DS_BACKGROUND_ONLY, &pbBuffer); } } else { // // Not in a domain, don't call DsGetDcName // uRet = ERROR_NO_SUCH_DOMAIN; } if (uRet || (pbBuffer == NULL)) { // // If we focus on a server and can't find a domain then look for an // enterprise server. This is the case if the focus server is a // standalone system. // if (Domain == FALSE) { Status = EnterpriseServerGet((LPTSTR) Focus, EnterpriseServer); goto LlsEnterpriseServerFindWExit; } return STATUS_NO_SUCH_DOMAIN; } else { lstrcpy(pDomain,pbBuffer->DomainName); } // // Go to DC and figure out if they are replicating anywhere, if so go // to that system. // Status = EnterpriseServerGet((LPTSTR) (pbBuffer->DomainControllerName), EnterpriseServer); if (pbBuffer != NULL) NetApiBufferFree(pbBuffer); LlsEnterpriseServerFindWExit: if (Status != STATUS_SUCCESS) return Status; Size = sizeof(LLS_CONNECT_INFO_0); Size += ((lstrlen(pDomain) + 1) * sizeof(TCHAR)); Size += ((lstrlen(EnterpriseServer) + 1) * sizeof(TCHAR)); pConnectInfo = (PLLS_CONNECT_INFO_0) MIDL_user_allocate(Size); if (pConnectInfo == NULL) return STATUS_NO_MEMORY; pConnectInfo->Domain = (LPTSTR) (((PBYTE) pConnectInfo) + sizeof(LLS_CONNECT_INFO_0)); pConnectInfo->EnterpriseServer = (LPTSTR) &pConnectInfo->Domain[lstrlen(pDomain) + 1]; lstrcpy(pConnectInfo->Domain, pDomain); lstrcpy(pConnectInfo->EnterpriseServer, EnterpriseServer); *BufPtr = (LPBYTE) pConnectInfo; return Status; } // LlsEnterpriseServerFindW ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsEnterpriseServerFindA( LPSTR Focus, DWORD Level, LPBYTE *BufPtr ) /*++ Routine Description: Arguments: Return Value: None. --*/ { #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsEnterpriseServerFindA\n")); #endif return STATUS_NOT_SUPPORTED; } // LlsEnterpriseServerFindA ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsConnectW( LPTSTR Server, LLS_HANDLE* Handle ) /*++ Routine Description: Arguments: Return Value: None. --*/ { RPC_STATUS Status; LPTSTR pszUuid = NULL; LPTSTR pszProtocolSequence = NULL; LPTSTR pszNetworkAddress = NULL; LPTSTR pszEndpoint = NULL; LPTSTR pszOptions = NULL; TCHAR pComputer[MAX_COMPUTERNAME_LENGTH + 1]; ULONG Size; PLOCAL_HANDLE pLocalHandle = NULL; handle_t prev_llsrpc_handle; #ifdef API_TRACE if (Server == NULL) dprintf(TEXT("LLSRPC.DLL: LlsConnectW: \n")); else dprintf(TEXT("LLSRPC.DLL: LlsConnectW: %s\n"), Server); #endif // // ** NEW - NT 5.0 ** // // The server name may either be a DNS name or a NetBIOS name. // if (Handle == NULL) return STATUS_INVALID_PARAMETER; *Handle = NULL; Size = sizeof(pComputer) / sizeof(TCHAR); GetComputerName(pComputer, &Size); if ((Server == NULL) || (*Server == TEXT('\0'))) { pszProtocolSequence = TEXT("ncalrpc"); pszEndpoint = TEXT(LLS_LPC_ENDPOINT); pszNetworkAddress = NULL; } else { pszProtocolSequence = TEXT("ncacn_np"); pszEndpoint = TEXT(LLS_NP_ENDPOINT); pszNetworkAddress = Server; } pLocalHandle = MIDL_user_allocate(sizeof(LOCAL_HANDLE)); if (pLocalHandle == NULL) return STATUS_NO_MEMORY; pLocalHandle->pszStringBinding = NULL; pLocalHandle->llsrpc_handle = NULL; pLocalHandle->Handle = NULL; ZeroMemory( pLocalHandle->szServerName, sizeof( pLocalHandle->szServerName ) ); if ( NULL != Server ) { lstrcpyn( pLocalHandle->szServerName, Server, sizeof( pLocalHandle->szServerName ) / sizeof( *pLocalHandle->szServerName ) - 1 ); } else { lstrcpy( pLocalHandle->szServerName, pComputer ); } // Compose a string binding Status = RpcStringBindingComposeW(pszUuid, pszProtocolSequence, pszNetworkAddress, pszEndpoint, pszOptions, &pLocalHandle->pszStringBinding); if(Status) { #if DBG dprintf(TEXT("LLSRPC RpcStringBindingComposeW Failed: 0x%lX\n"), Status); #endif if(pLocalHandle->pszStringBinding) { RpcStringFree(&pLocalHandle->pszStringBinding); pLocalHandle->pszStringBinding = NULL; } MIDL_user_free( pLocalHandle ); return I_RpcMapWin32Status(Status); } RtlEnterCriticalSection( &g_RpcHandleLock ); prev_llsrpc_handle = llsrpc_handle; llsrpc_handle = NULL; // Bind using the created string binding... Status = RpcBindingFromStringBindingW(pLocalHandle->pszStringBinding, &llsrpc_handle); if(Status) { #if DBG dprintf(TEXT("LLSRPC RpcBindingFromStringBindingW Failed: 0x%lX\n"), Status); #endif if(llsrpc_handle) { RpcBindingFree(llsrpc_handle); llsrpc_handle = prev_llsrpc_handle; } Status = I_RpcMapWin32Status(Status); } if ( NT_SUCCESS( Status ) ) { pLocalHandle->llsrpc_handle = llsrpc_handle; try { Status = LlsrConnect(&pLocalHandle->Handle, pComputer); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("LLSRPC ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } if ( NT_SUCCESS( Status ) ) { // get server capabilities try { LlsrCapabilityGet( pLocalHandle->Handle, sizeof( pLocalHandle->Capabilities ), pLocalHandle->Capabilities ); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); if ( RPC_NT_PROCNUM_OUT_OF_RANGE == Status ) { // 'salright; API doesn't exist at target server (it's running 3.51) ZeroMemory( pLocalHandle->Capabilities, sizeof( pLocalHandle->Capabilities ) ); Status = STATUS_SUCCESS; } else { #if DBG dprintf(TEXT("LLSRPC ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } } if ( !NT_SUCCESS( Status ) ) { LlsClose( pLocalHandle ); } else { *Handle = (LLS_HANDLE) pLocalHandle; } } else { if(pLocalHandle->pszStringBinding) { RpcStringFree(&pLocalHandle->pszStringBinding); pLocalHandle->pszStringBinding = NULL; } if(llsrpc_handle) { RpcBindingFree(llsrpc_handle); llsrpc_handle = prev_llsrpc_handle; } MIDL_user_free( pLocalHandle ); } } else { if(pLocalHandle->pszStringBinding) RpcStringFree(&pLocalHandle->pszStringBinding); MIDL_user_free( pLocalHandle ); } llsrpc_handle = prev_llsrpc_handle; RtlLeaveCriticalSection( &g_RpcHandleLock ); return Status; } // LlsConnectW ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsConnectA( LPSTR Server, LLS_HANDLE* Handle ) /*++ Routine Description: Arguments: Return Value: None. --*/ { #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsConnectA\n")); #endif return STATUS_NOT_SUPPORTED; } // LlsConnectA ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsConnectEnterpriseW( LPTSTR Focus, LLS_HANDLE* Handle, DWORD Level, LPBYTE *BufPtr ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; PLLS_CONNECT_INFO_0 pConnectInfo; Status = LlsEnterpriseServerFindW(Focus, Level, BufPtr); if (Status) return Status; pConnectInfo = (PLLS_CONNECT_INFO_0) *BufPtr; Status = LlsConnectW(pConnectInfo->EnterpriseServer, Handle); return Status; } // LlsConnectEnterpriseW ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsConnectEnterpriseA( LPSTR Focus, LLS_HANDLE* Handle, DWORD Level, LPBYTE *BufPtr ) /*++ Routine Description: Arguments: Return Value: None. --*/ { #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsConnectEnterpriseA\n")); #endif return STATUS_NOT_SUPPORTED; } // LlsConnectEnterpriseA ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsClose( LLS_HANDLE Handle ) /*++ Routine Description: Arguments: Return Value: None. --*/ { RPC_STATUS Status; NTSTATUS NtStatus = STATUS_SUCCESS; PLOCAL_HANDLE pLocalHandle; pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) return STATUS_INVALID_PARAMETER; try { NtStatus = LlsrCloseEx(&(pLocalHandle->Handle)); } except (TRUE) { NtStatus = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: LlsrCloseEx RPC Exception: 0x%lX\n"), NtStatus); #endif } // // LlsrCloseEx was added for NT 5.0. Check for downlevel. // if (NtStatus == RPC_S_PROCNUM_OUT_OF_RANGE) { try { NtStatus = LlsrClose(pLocalHandle->Handle); } except (TRUE) { NtStatus = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: LlsrClose RPC Exception: 0x%lX\n"), NtStatus); #endif } } try { Status = RpcStringFree(&pLocalHandle->pszStringBinding); if (Status ) { NtStatus = I_RpcMapWin32Status(Status); #if DBG dprintf(TEXT("LLSRPC.DLL: LlsClose - RpcStringFree returned: 0x%lX\n"), NtStatus); #endif } Status = RpcBindingFree(&pLocalHandle->llsrpc_handle); if (Status ) { NtStatus = I_RpcMapWin32Status(Status); #if DBG dprintf(TEXT("LLSRPC.DLL: LlsClose - RpcBindingFree returned: 0x%lX\n"), NtStatus); #endif } } except (TRUE) { NtStatus = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), NtStatus); #endif } MIDL_user_free(pLocalHandle); return NtStatus; } // LlsClose ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsFreeMemory( PVOID BufPtr ) /*++ Routine Description: Arguments: Return Value: None. --*/ { MIDL_user_free( BufPtr ); return STATUS_SUCCESS; } // LlsFreeMemory ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsLicenseEnumW( LLS_HANDLE Handle, DWORD Level, LPBYTE* bufptr, DWORD PrefMaxLen, LPDWORD EntriesRead, LPDWORD TotalEntries, LPDWORD ResumeHandle ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; GENERIC_INFO_CONTAINER GenericInfoContainer; GENERIC_ENUM_STRUCT InfoStruct; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsLicenseEnumW\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) return STATUS_INVALID_PARAMETER; GenericInfoContainer.Buffer = NULL; GenericInfoContainer.EntriesRead = 0; InfoStruct.Container = &GenericInfoContainer; InfoStruct.Level = Level; try { Status = LlsrLicenseEnumW( pLocalHandle->Handle, (PLLS_LICENSE_ENUM_STRUCTW) &InfoStruct, PrefMaxLen, TotalEntries, ResumeHandle ); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } if ((Status == STATUS_SUCCESS) || (Status == STATUS_MORE_ENTRIES)) { *bufptr = (LPBYTE) GenericInfoContainer.Buffer; *EntriesRead = GenericInfoContainer.EntriesRead; } return Status; } // LlsLicenseEnumW ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsLicenseEnumA( LLS_HANDLE Handle, DWORD Level, LPBYTE* bufptr, DWORD PrefMaxLen, LPDWORD EntriesRead, LPDWORD TotalEntries, LPDWORD ResumeHandle ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; GENERIC_INFO_CONTAINER GenericInfoContainer; GENERIC_ENUM_STRUCT InfoStruct; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsLicenseEnumA\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) return STATUS_INVALID_PARAMETER; GenericInfoContainer.Buffer = NULL; GenericInfoContainer.EntriesRead = 0; InfoStruct.Container = &GenericInfoContainer; InfoStruct.Level = Level; try { Status = LlsrLicenseEnumA( pLocalHandle->Handle, (PLLS_LICENSE_ENUM_STRUCTA) &InfoStruct, PrefMaxLen, TotalEntries, ResumeHandle ); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } if ((Status == STATUS_SUCCESS) || (Status == STATUS_MORE_ENTRIES)) { *bufptr = (LPBYTE) GenericInfoContainer.Buffer; *EntriesRead = GenericInfoContainer.EntriesRead; } return Status; } // LlsLicenseEnumA ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsLicenseAddW( IN LLS_HANDLE Handle, IN DWORD Level, // Level 0 supported IN LPBYTE bufptr ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsLicenseAddW\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) return STATUS_INVALID_PARAMETER; try { Status = LlsrLicenseAddW(pLocalHandle->Handle, Level, (PVOID) bufptr); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } return Status; } // LlsLicenseAddW ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsLicenseAddA( IN LLS_HANDLE Handle, IN DWORD Level, // Level 0 supported IN LPBYTE bufptr ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsLicenseAddA\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) return STATUS_INVALID_PARAMETER; try { Status = LlsrLicenseAddA(pLocalHandle->Handle, Level, (PVOID) bufptr); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } return Status; } // LlsLicenseAddA ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsProductEnumW( LLS_HANDLE Handle, DWORD Level, LPBYTE* bufptr, DWORD PrefMaxLen, LPDWORD EntriesRead, LPDWORD TotalEntries, LPDWORD ResumeHandle ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; GENERIC_INFO_CONTAINER GenericInfoContainer; GENERIC_ENUM_STRUCT InfoStruct; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsProductEnumW\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) return STATUS_INVALID_PARAMETER; GenericInfoContainer.Buffer = NULL; GenericInfoContainer.EntriesRead = 0; InfoStruct.Container = &GenericInfoContainer; InfoStruct.Level = Level; try { Status = LlsrProductEnumW( pLocalHandle->Handle, (PLLS_PRODUCT_ENUM_STRUCTW) &InfoStruct, PrefMaxLen, TotalEntries, ResumeHandle ); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } if ((Status == STATUS_SUCCESS) || (Status == STATUS_MORE_ENTRIES)) { *bufptr = (LPBYTE) GenericInfoContainer.Buffer; *EntriesRead = GenericInfoContainer.EntriesRead; } return Status; } // LlsProductEnumW ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsProductEnumA( LLS_HANDLE Handle, DWORD Level, LPBYTE* bufptr, DWORD PrefMaxLen, LPDWORD EntriesRead, LPDWORD TotalEntries, LPDWORD ResumeHandle ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; GENERIC_INFO_CONTAINER GenericInfoContainer; GENERIC_ENUM_STRUCT InfoStruct; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsProductEnumA\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) return STATUS_INVALID_PARAMETER; GenericInfoContainer.Buffer = NULL; GenericInfoContainer.EntriesRead = 0; InfoStruct.Container = &GenericInfoContainer; InfoStruct.Level = Level; try { Status = LlsrProductEnumA( pLocalHandle->Handle, (PLLS_PRODUCT_ENUM_STRUCTA) &InfoStruct, PrefMaxLen, TotalEntries, ResumeHandle ); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } if ((Status == STATUS_SUCCESS) || (Status == STATUS_MORE_ENTRIES)) { *bufptr = (LPBYTE) GenericInfoContainer.Buffer; *EntriesRead = GenericInfoContainer.EntriesRead; } return Status; } // LlsProductEnumA ///////////////////////////////////////////////////////////////////////// NTSTATUS LlsProductAddW( IN LLS_REPL_HANDLE Handle, IN LPWSTR ProductFamily, IN LPWSTR Product, IN LPWSTR Version ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsProductAddW\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) return STATUS_INVALID_PARAMETER; try { Status = LlsrProductAddW(pLocalHandle->Handle, ProductFamily, Product, Version); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } return Status; } // LlsProductAddW ///////////////////////////////////////////////////////////////////////// NTSTATUS LlsProductAddA( IN LLS_REPL_HANDLE Handle, IN LPSTR ProductFamily, IN LPSTR Product, IN LPSTR Version ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsProductAddA\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) return STATUS_INVALID_PARAMETER; try { Status = LlsrProductAddA(pLocalHandle->Handle, ProductFamily, Product, Version); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } return Status; } // LlsProductAddA ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsProductUserEnumW( LLS_HANDLE Handle, LPTSTR Product, DWORD Level, LPBYTE* bufptr, DWORD PrefMaxLen, LPDWORD EntriesRead, LPDWORD TotalEntries, LPDWORD ResumeHandle ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; GENERIC_INFO_CONTAINER GenericInfoContainer; GENERIC_ENUM_STRUCT InfoStruct; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsProductUserEnumW\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) return STATUS_INVALID_PARAMETER; GenericInfoContainer.Buffer = NULL; GenericInfoContainer.EntriesRead = 0; InfoStruct.Container = &GenericInfoContainer; InfoStruct.Level = Level; try { Status = LlsrProductUserEnumW( pLocalHandle->Handle, Product, (PLLS_PRODUCT_USER_ENUM_STRUCTW) &InfoStruct, PrefMaxLen, TotalEntries, ResumeHandle ); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } if ((Status == STATUS_SUCCESS) || (Status == STATUS_MORE_ENTRIES)) { *bufptr = (LPBYTE) GenericInfoContainer.Buffer; *EntriesRead = GenericInfoContainer.EntriesRead; } return Status; } // LlsProductUserEnumW ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsProductUserEnumA( LLS_HANDLE Handle, LPSTR Product, DWORD Level, LPBYTE* bufptr, DWORD PrefMaxLen, LPDWORD EntriesRead, LPDWORD TotalEntries, LPDWORD ResumeHandle ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; GENERIC_INFO_CONTAINER GenericInfoContainer; GENERIC_ENUM_STRUCT InfoStruct; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsProductUserEnumA\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) return STATUS_INVALID_PARAMETER; GenericInfoContainer.Buffer = NULL; GenericInfoContainer.EntriesRead = 0; InfoStruct.Container = &GenericInfoContainer; InfoStruct.Level = Level; try { Status = LlsrProductUserEnumA( pLocalHandle->Handle, Product, (PLLS_PRODUCT_USER_ENUM_STRUCTA) &InfoStruct, PrefMaxLen, TotalEntries, ResumeHandle ); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } if ((Status == STATUS_SUCCESS) || (Status == STATUS_MORE_ENTRIES)) { *bufptr = (LPBYTE) GenericInfoContainer.Buffer; *EntriesRead = GenericInfoContainer.EntriesRead; } return Status; } // LlsProductUserEnumA ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsProductServerEnumW( LLS_HANDLE Handle, LPTSTR Product, DWORD Level, LPBYTE* bufptr, DWORD PrefMaxLen, LPDWORD EntriesRead, LPDWORD TotalEntries, LPDWORD ResumeHandle ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; GENERIC_INFO_CONTAINER GenericInfoContainer; GENERIC_ENUM_STRUCT InfoStruct; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsProductServerEnumW\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) return STATUS_INVALID_PARAMETER; GenericInfoContainer.Buffer = NULL; GenericInfoContainer.EntriesRead = 0; InfoStruct.Container = &GenericInfoContainer; InfoStruct.Level = Level; try { Status = LlsrProductServerEnumW( pLocalHandle->Handle, Product, (PLLS_SERVER_PRODUCT_ENUM_STRUCTW) &InfoStruct, PrefMaxLen, TotalEntries, ResumeHandle ); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } if ((Status == STATUS_SUCCESS) || (Status == STATUS_MORE_ENTRIES)) { *bufptr = (LPBYTE) GenericInfoContainer.Buffer; *EntriesRead = GenericInfoContainer.EntriesRead; } return Status; } // LlsProductServerEnumW ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsProductServerEnumA( LLS_HANDLE Handle, LPSTR Product, DWORD Level, LPBYTE* bufptr, DWORD PrefMaxLen, LPDWORD EntriesRead, LPDWORD TotalEntries, LPDWORD ResumeHandle ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; GENERIC_INFO_CONTAINER GenericInfoContainer; GENERIC_ENUM_STRUCT InfoStruct; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsProductServerEnumA\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) return STATUS_INVALID_PARAMETER; GenericInfoContainer.Buffer = NULL; GenericInfoContainer.EntriesRead = 0; InfoStruct.Container = &GenericInfoContainer; InfoStruct.Level = Level; try { Status = LlsrProductServerEnumA( pLocalHandle->Handle, Product, (PLLS_SERVER_PRODUCT_ENUM_STRUCTA) &InfoStruct, PrefMaxLen, TotalEntries, ResumeHandle ); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } if ((Status == STATUS_SUCCESS) || (Status == STATUS_MORE_ENTRIES)) { *bufptr = (LPBYTE) GenericInfoContainer.Buffer; *EntriesRead = GenericInfoContainer.EntriesRead; } return Status; } // LlsProductServerEnumA ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsProductLicenseEnumW( LLS_HANDLE Handle, LPTSTR Product, DWORD Level, LPBYTE* bufptr, DWORD PrefMaxLen, LPDWORD EntriesRead, LPDWORD TotalEntries, LPDWORD ResumeHandle ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; GENERIC_INFO_CONTAINER GenericInfoContainer; GENERIC_ENUM_STRUCT InfoStruct; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsProductLicenseEnumW\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) return STATUS_INVALID_PARAMETER; GenericInfoContainer.Buffer = NULL; GenericInfoContainer.EntriesRead = 0; InfoStruct.Container = &GenericInfoContainer; InfoStruct.Level = Level; try { Status = LlsrProductLicenseEnumW( pLocalHandle->Handle, Product, (PLLS_PRODUCT_LICENSE_ENUM_STRUCTW) &InfoStruct, PrefMaxLen, TotalEntries, ResumeHandle ); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } if ((Status == STATUS_SUCCESS) || (Status == STATUS_MORE_ENTRIES)) { *bufptr = (LPBYTE) GenericInfoContainer.Buffer; *EntriesRead = GenericInfoContainer.EntriesRead; } return Status; } // LlsProductLicenseEnumW ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsProductLicenseEnumA( LLS_HANDLE Handle, LPSTR Product, DWORD Level, LPBYTE* bufptr, DWORD PrefMaxLen, LPDWORD EntriesRead, LPDWORD TotalEntries, LPDWORD ResumeHandle ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; GENERIC_INFO_CONTAINER GenericInfoContainer; GENERIC_ENUM_STRUCT InfoStruct; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsProductLicenseEnumA\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) return STATUS_INVALID_PARAMETER; GenericInfoContainer.Buffer = NULL; GenericInfoContainer.EntriesRead = 0; InfoStruct.Container = &GenericInfoContainer; InfoStruct.Level = Level; try { Status = LlsrProductLicenseEnumA( pLocalHandle->Handle, Product, (PLLS_PRODUCT_LICENSE_ENUM_STRUCTA) &InfoStruct, PrefMaxLen, TotalEntries, ResumeHandle ); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } if ((Status == STATUS_SUCCESS) || (Status == STATUS_MORE_ENTRIES)) { *bufptr = (LPBYTE) GenericInfoContainer.Buffer; *EntriesRead = GenericInfoContainer.EntriesRead; } return Status; } // LlsProductLicenseEnumA ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsUserEnumW( LLS_HANDLE Handle, DWORD Level, LPBYTE* bufptr, DWORD PrefMaxLen, LPDWORD EntriesRead, LPDWORD TotalEntries, LPDWORD ResumeHandle ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; GENERIC_INFO_CONTAINER GenericInfoContainer; GENERIC_ENUM_STRUCT InfoStruct; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsUserEnumW\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) return STATUS_INVALID_PARAMETER; GenericInfoContainer.Buffer = NULL; GenericInfoContainer.EntriesRead = 0; InfoStruct.Container = &GenericInfoContainer; InfoStruct.Level = Level; try { Status = LlsrUserEnumW( pLocalHandle->Handle, (PLLS_USER_ENUM_STRUCTW) &InfoStruct, PrefMaxLen, TotalEntries, ResumeHandle ); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } if ((Status == STATUS_SUCCESS) || (Status == STATUS_MORE_ENTRIES)) { *bufptr = (LPBYTE) GenericInfoContainer.Buffer; *EntriesRead = GenericInfoContainer.EntriesRead; } return Status; } // LlsUserEnumW ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsUserEnumA( LLS_HANDLE Handle, DWORD Level, LPBYTE* bufptr, DWORD PrefMaxLen, LPDWORD EntriesRead, LPDWORD TotalEntries, LPDWORD ResumeHandle ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; GENERIC_INFO_CONTAINER GenericInfoContainer; GENERIC_ENUM_STRUCT InfoStruct; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsUserEnumA\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) return STATUS_INVALID_PARAMETER; GenericInfoContainer.Buffer = NULL; GenericInfoContainer.EntriesRead = 0; InfoStruct.Container = &GenericInfoContainer; InfoStruct.Level = Level; try { Status = LlsrUserEnumA( pLocalHandle->Handle, (PLLS_USER_ENUM_STRUCTA) &InfoStruct, PrefMaxLen, TotalEntries, ResumeHandle ); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } if ((Status == STATUS_SUCCESS) || (Status == STATUS_MORE_ENTRIES)) { *bufptr = (LPBYTE) GenericInfoContainer.Buffer; *EntriesRead = GenericInfoContainer.EntriesRead; } return Status; } // LlsUserEnumA ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsUserInfoGetW( IN LLS_HANDLE Handle, IN LPWSTR User, IN DWORD Level, OUT LPBYTE* bufptr ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsUserInfoGetW\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if ((pLocalHandle == NULL) || (bufptr == NULL)) return STATUS_INVALID_PARAMETER; *bufptr = NULL; try { Status = LlsrUserInfoGetW(pLocalHandle->Handle, User, Level, (PLLS_USER_INFOW *) bufptr); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } return Status; } // LlsUserInfoGetW ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsUserInfoGetA( IN LLS_HANDLE Handle, IN LPSTR User, IN DWORD Level, OUT LPBYTE* bufptr ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsUserInfoGetA\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if ((pLocalHandle == NULL) || (bufptr == NULL)) return STATUS_INVALID_PARAMETER; *bufptr = NULL; try { Status = LlsrUserInfoGetA(pLocalHandle->Handle, User, Level, (PVOID) bufptr); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } return Status; } // LlsUserInfoGetA ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsUserInfoSetW( IN LLS_HANDLE Handle, IN LPWSTR User, IN DWORD Level, IN LPBYTE bufptr // Level 1 supported ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsUserInfoSetW\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) return STATUS_INVALID_PARAMETER; try { Status = LlsrUserInfoSetW(pLocalHandle->Handle, User, Level, (PLLS_USER_INFOW) bufptr); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } return Status; } // LlsUserInfoSetW ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsUserInfoSetA( IN LLS_HANDLE Handle, IN LPSTR User, IN DWORD Level, IN LPBYTE bufptr ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsUserInfoSetA\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) return STATUS_INVALID_PARAMETER; try { Status = LlsrUserInfoSetA(pLocalHandle->Handle, User, Level, (PVOID) bufptr); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } return Status; } // LlsUserInfoSetA ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsUserDeleteW( IN LLS_HANDLE Handle, IN LPWSTR User ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsUserDeleteW\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) return STATUS_INVALID_PARAMETER; try { Status = LlsrUserDeleteW(pLocalHandle->Handle, User); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } return Status; } // LlsUserDeleteW ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsUserDeleteA( IN LLS_HANDLE Handle, IN LPSTR User ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsUserDeleteA\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) return STATUS_INVALID_PARAMETER; try { Status = LlsrUserDeleteA(pLocalHandle->Handle, User); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } return Status; } // LlsUserDeleteA ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsUserProductEnumW( LLS_HANDLE Handle, LPTSTR User, DWORD Level, LPBYTE* bufptr, DWORD PrefMaxLen, LPDWORD EntriesRead, LPDWORD TotalEntries, LPDWORD ResumeHandle ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; GENERIC_INFO_CONTAINER GenericInfoContainer; GENERIC_ENUM_STRUCT InfoStruct; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsUserProductEnumW\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) return STATUS_INVALID_PARAMETER; GenericInfoContainer.Buffer = NULL; GenericInfoContainer.EntriesRead = 0; InfoStruct.Container = &GenericInfoContainer; InfoStruct.Level = Level; try { Status = LlsrUserProductEnumW( pLocalHandle->Handle, User, (PLLS_USER_PRODUCT_ENUM_STRUCTW) &InfoStruct, PrefMaxLen, TotalEntries, ResumeHandle ); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } if ((Status == STATUS_SUCCESS) || (Status == STATUS_MORE_ENTRIES)) { *bufptr = (LPBYTE) GenericInfoContainer.Buffer; *EntriesRead = GenericInfoContainer.EntriesRead; } return Status; } // LlsUserProductEnumW ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsUserProductEnumA( LLS_HANDLE Handle, LPSTR User, DWORD Level, LPBYTE* bufptr, DWORD PrefMaxLen, LPDWORD EntriesRead, LPDWORD TotalEntries, LPDWORD ResumeHandle ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; GENERIC_INFO_CONTAINER GenericInfoContainer; GENERIC_ENUM_STRUCT InfoStruct; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsUserProductEnumA\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) return STATUS_INVALID_PARAMETER; GenericInfoContainer.Buffer = NULL; GenericInfoContainer.EntriesRead = 0; InfoStruct.Container = &GenericInfoContainer; InfoStruct.Level = Level; try { Status = LlsrUserProductEnumA( pLocalHandle->Handle, User, (PLLS_USER_PRODUCT_ENUM_STRUCTA) &InfoStruct, PrefMaxLen, TotalEntries, ResumeHandle ); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } if ((Status == STATUS_SUCCESS) || (Status == STATUS_MORE_ENTRIES)) { *bufptr = (LPBYTE) GenericInfoContainer.Buffer; *EntriesRead = GenericInfoContainer.EntriesRead; } return Status; } // LlsUserProductEnumA ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsUserProductDeleteW( IN LLS_HANDLE Handle, IN LPWSTR User, IN LPWSTR Product ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsUserProductDeleteW\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) return STATUS_INVALID_PARAMETER; try { Status = LlsrUserProductDeleteW(pLocalHandle->Handle, User, Product); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } return Status; } // LlsUserProductDeleteW ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsUserProductDeleteA( IN LLS_HANDLE Handle, IN LPSTR User, IN LPSTR Product ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsUserProductDeleteA\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) return STATUS_INVALID_PARAMETER; try { Status = LlsrUserProductDeleteA(pLocalHandle->Handle, User, Product); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } return Status; } // LlsUserProductDeleteA ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsGroupEnumW( LLS_HANDLE Handle, DWORD Level, LPBYTE* bufptr, DWORD PrefMaxLen, LPDWORD EntriesRead, LPDWORD TotalEntries, LPDWORD ResumeHandle ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; GENERIC_INFO_CONTAINER GenericInfoContainer; GENERIC_ENUM_STRUCT InfoStruct; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsGroupEnumW\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) return STATUS_INVALID_PARAMETER; GenericInfoContainer.Buffer = NULL; GenericInfoContainer.EntriesRead = 0; InfoStruct.Container = &GenericInfoContainer; InfoStruct.Level = Level; try { Status = LlsrMappingEnumW( pLocalHandle->Handle, (PLLS_MAPPING_ENUM_STRUCTW) &InfoStruct, PrefMaxLen, TotalEntries, ResumeHandle ); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } if ((Status == STATUS_SUCCESS) || (Status == STATUS_MORE_ENTRIES)) { *bufptr = (LPBYTE) GenericInfoContainer.Buffer; *EntriesRead = GenericInfoContainer.EntriesRead; } return Status; } // LlsGroupEnumW ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsGroupEnumA( LLS_HANDLE Handle, DWORD Level, LPBYTE* bufptr, DWORD PrefMaxLen, LPDWORD EntriesRead, LPDWORD TotalEntries, LPDWORD ResumeHandle ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; GENERIC_INFO_CONTAINER GenericInfoContainer; GENERIC_ENUM_STRUCT InfoStruct; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsGroupEnumA\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) return STATUS_INVALID_PARAMETER; GenericInfoContainer.Buffer = NULL; GenericInfoContainer.EntriesRead = 0; InfoStruct.Container = &GenericInfoContainer; InfoStruct.Level = Level; try { Status = LlsrMappingEnumA( pLocalHandle->Handle, (PLLS_MAPPING_ENUM_STRUCTA) &InfoStruct, PrefMaxLen, TotalEntries, ResumeHandle ); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } if ((Status == STATUS_SUCCESS) || (Status == STATUS_MORE_ENTRIES)) { *bufptr = (LPBYTE) GenericInfoContainer.Buffer; *EntriesRead = GenericInfoContainer.EntriesRead; } return Status; } // LlsGroupEnumA ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsGroupInfoGetW( IN LLS_HANDLE Handle, IN LPWSTR Group, IN DWORD Level, OUT LPBYTE* bufptr ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsGroupInfoGetW\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if ((pLocalHandle == NULL) || (bufptr == NULL)) return STATUS_INVALID_PARAMETER; *bufptr = NULL; try { Status = LlsrMappingInfoGetW(pLocalHandle->Handle, Group, Level, (PVOID) bufptr); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } return Status; } // LlsGroupInfoGetW ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsGroupInfoGetA( IN LLS_HANDLE Handle, IN LPSTR Group, IN DWORD Level, OUT LPBYTE* bufptr ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsGroupInfoGetA\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if ((pLocalHandle == NULL) || (bufptr == NULL)) return STATUS_INVALID_PARAMETER; *bufptr = NULL; try { Status = LlsrMappingInfoGetA(pLocalHandle->Handle, Group, Level, (PVOID) bufptr); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } return Status; } // LlsGroupInfoGetA ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsGroupInfoSetW( IN LLS_HANDLE Handle, IN LPWSTR Group, IN DWORD Level, IN LPBYTE bufptr ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsGroupInfoSetW\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) return STATUS_INVALID_PARAMETER; try { Status = LlsrMappingInfoSetW(pLocalHandle->Handle, Group, Level, (PVOID) bufptr); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } return Status; } // LlsGroupInfoSetW ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsGroupInfoSetA( IN LLS_HANDLE Handle, IN LPSTR Group, IN DWORD Level, IN LPBYTE bufptr ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsGroupInfoSetA\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) return STATUS_INVALID_PARAMETER; try { Status = LlsrMappingInfoSetA(pLocalHandle->Handle, Group, Level, (PVOID) bufptr); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } return Status; } // LlsGroupInfoSetA ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsGroupUserEnumW( LLS_HANDLE Handle, LPTSTR Group, DWORD Level, LPBYTE* bufptr, DWORD PrefMaxLen, LPDWORD EntriesRead, LPDWORD TotalEntries, LPDWORD ResumeHandle ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; GENERIC_INFO_CONTAINER GenericInfoContainer; GENERIC_ENUM_STRUCT InfoStruct; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsGroupUserEnumW\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) return STATUS_INVALID_PARAMETER; GenericInfoContainer.Buffer = NULL; GenericInfoContainer.EntriesRead = 0; InfoStruct.Container = &GenericInfoContainer; InfoStruct.Level = Level; try { Status = LlsrMappingUserEnumW( pLocalHandle->Handle, Group, (PLLS_USER_ENUM_STRUCTW) &InfoStruct, PrefMaxLen, TotalEntries, ResumeHandle ); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } if ((Status == STATUS_SUCCESS) || (Status == STATUS_MORE_ENTRIES)) { *bufptr = (LPBYTE) GenericInfoContainer.Buffer; *EntriesRead = GenericInfoContainer.EntriesRead; } return Status; } // LlsGroupUserEnumW ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsGroupUserEnumA( LLS_HANDLE Handle, LPSTR Group, DWORD Level, LPBYTE* bufptr, DWORD PrefMaxLen, LPDWORD EntriesRead, LPDWORD TotalEntries, LPDWORD ResumeHandle ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; GENERIC_INFO_CONTAINER GenericInfoContainer; GENERIC_ENUM_STRUCT InfoStruct; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsGroupUserEnumA\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) return STATUS_INVALID_PARAMETER; GenericInfoContainer.Buffer = NULL; GenericInfoContainer.EntriesRead = 0; InfoStruct.Container = &GenericInfoContainer; InfoStruct.Level = Level; try { Status = LlsrMappingUserEnumA( pLocalHandle->Handle, Group, (PLLS_USER_ENUM_STRUCTA) &InfoStruct, PrefMaxLen, TotalEntries, ResumeHandle ); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } if ((Status == STATUS_SUCCESS) || (Status == STATUS_MORE_ENTRIES)) { *bufptr = (LPBYTE) GenericInfoContainer.Buffer; *EntriesRead = GenericInfoContainer.EntriesRead; } return Status; } // LlsGroupUserEnumA ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsGroupUserAddW( IN LLS_HANDLE Handle, IN LPWSTR Group, IN LPWSTR User ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsGroupUserAddW\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) return STATUS_INVALID_PARAMETER; try { Status = LlsrMappingUserAddW(pLocalHandle->Handle, Group, User); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } return Status; } // LlsGroupUserAddW ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsGroupUserAddA( IN LLS_HANDLE Handle, IN LPSTR Group, IN LPSTR User ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsGroupUserAddA\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) return STATUS_INVALID_PARAMETER; try { Status = LlsrMappingUserAddA(pLocalHandle->Handle, Group, User); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } return Status; } // LlsGroupUserAddA ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsGroupUserDeleteW( IN LLS_HANDLE Handle, IN LPWSTR Group, IN LPWSTR User ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsGroupUserDeleteW\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) return STATUS_INVALID_PARAMETER; try { Status = LlsrMappingUserDeleteW(pLocalHandle->Handle, Group, User); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } return Status; } // LlsGroupUserDeleteW ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsGroupUserDeleteA( IN LLS_HANDLE Handle, IN LPSTR Group, IN LPSTR User ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsGroupUserDeleteA\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) return STATUS_INVALID_PARAMETER; try { Status = LlsrMappingUserDeleteA(pLocalHandle->Handle, Group, User); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } return Status; } // LlsGroupUserDeleteA ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsGroupAddW( IN LLS_HANDLE Handle, IN DWORD Level, IN LPBYTE bufptr ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsGroupAddW\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) return STATUS_INVALID_PARAMETER; try { Status = LlsrMappingAddW(pLocalHandle->Handle, Level, (PVOID) bufptr); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } return Status; } // LlsGroupAddW ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsGroupAddA( IN LLS_HANDLE Handle, IN DWORD Level, IN LPBYTE bufptr ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsGroupAddA\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) return STATUS_INVALID_PARAMETER; try { Status = LlsrMappingAddA(pLocalHandle->Handle, Level, (PVOID) bufptr); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } return Status; } // LlsGroupAddA ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsGroupDeleteW( IN LLS_HANDLE Handle, IN LPWSTR Group ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsGroupDeleteW\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) return STATUS_INVALID_PARAMETER; try { Status = LlsrMappingDeleteW(pLocalHandle->Handle, Group); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } return Status; } // LlsGroupDeleteW ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsGroupDeleteA( IN LLS_HANDLE Handle, IN LPSTR Group ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: GroupDeleteA\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) return STATUS_INVALID_PARAMETER; try { Status = LlsrMappingDeleteA(pLocalHandle->Handle, Group); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } return Status; } // LlsGroupDeleteA #ifdef OBSOLETE ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsServerEnumW( LLS_HANDLE Handle, LPWSTR Server, DWORD Level, LPBYTE* bufptr, DWORD PrefMaxLen, LPDWORD EntriesRead, LPDWORD TotalEntries, LPDWORD ResumeHandle ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; GENERIC_INFO_CONTAINER GenericInfoContainer; GENERIC_ENUM_STRUCT InfoStruct; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsServerEnumW\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) return STATUS_INVALID_PARAMETER; GenericInfoContainer.Buffer = NULL; GenericInfoContainer.EntriesRead = 0; InfoStruct.Container = &GenericInfoContainer; InfoStruct.Level = Level; try { Status = LlsrServerEnumW( pLocalHandle->Handle, Server, (PLLS_SERVER_ENUM_STRUCTW) &InfoStruct, PrefMaxLen, TotalEntries, ResumeHandle ); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } if ((Status == STATUS_SUCCESS) || (Status == STATUS_MORE_ENTRIES)) { *bufptr = (LPBYTE) GenericInfoContainer.Buffer; *EntriesRead = GenericInfoContainer.EntriesRead; } return Status; } // LlsServerEnumW ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsServerEnumA( LLS_HANDLE Handle, LPSTR Server, DWORD Level, LPBYTE* bufptr, DWORD PrefMaxLen, LPDWORD EntriesRead, LPDWORD TotalEntries, LPDWORD ResumeHandle ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; GENERIC_INFO_CONTAINER GenericInfoContainer; GENERIC_ENUM_STRUCT InfoStruct; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsServerEnumA\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) return STATUS_INVALID_PARAMETER; GenericInfoContainer.Buffer = NULL; GenericInfoContainer.EntriesRead = 0; InfoStruct.Container = &GenericInfoContainer; InfoStruct.Level = Level; try { Status = LlsrServerEnumA( pLocalHandle->Handle, Server, (PLLS_SERVER_ENUM_STRUCTA) &InfoStruct, PrefMaxLen, TotalEntries, ResumeHandle ); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } if ((Status == STATUS_SUCCESS) || (Status == STATUS_MORE_ENTRIES)) { *bufptr = (LPBYTE) GenericInfoContainer.Buffer; *EntriesRead = GenericInfoContainer.EntriesRead; } return Status; } // LlsServerEnumA ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsServerProductEnumW( LLS_HANDLE Handle, LPWSTR Server, DWORD Level, LPBYTE* bufptr, DWORD PrefMaxLen, LPDWORD EntriesRead, LPDWORD TotalEntries, LPDWORD ResumeHandle ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; GENERIC_INFO_CONTAINER GenericInfoContainer; GENERIC_ENUM_STRUCT InfoStruct; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsServerProductEnumW\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) return STATUS_INVALID_PARAMETER; GenericInfoContainer.Buffer = NULL; GenericInfoContainer.EntriesRead = 0; InfoStruct.Container = &GenericInfoContainer; InfoStruct.Level = Level; try { Status = LlsrServerProductEnumW( pLocalHandle->Handle, Server, (PLLS_SERVER_PRODUCT_ENUM_STRUCTW) &InfoStruct, PrefMaxLen, TotalEntries, ResumeHandle ); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } if ((Status == STATUS_SUCCESS) || (Status == STATUS_MORE_ENTRIES)) { *bufptr = (LPBYTE) GenericInfoContainer.Buffer; *EntriesRead = GenericInfoContainer.EntriesRead; } return Status; } // LlsServerProductEnumW ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsServerProductEnumA( LLS_HANDLE Handle, LPSTR Server, DWORD Level, LPBYTE* bufptr, DWORD PrefMaxLen, LPDWORD EntriesRead, LPDWORD TotalEntries, LPDWORD ResumeHandle ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; GENERIC_INFO_CONTAINER GenericInfoContainer; GENERIC_ENUM_STRUCT InfoStruct; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsServerProductEnumA\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) return STATUS_INVALID_PARAMETER; GenericInfoContainer.Buffer = NULL; GenericInfoContainer.EntriesRead = 0; InfoStruct.Container = &GenericInfoContainer; InfoStruct.Level = Level; try { Status = LlsrServerProductEnumA( pLocalHandle->Handle, Server, (PLLS_SERVER_PRODUCT_ENUM_STRUCTA) &InfoStruct, PrefMaxLen, TotalEntries, ResumeHandle ); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } if ((Status == STATUS_SUCCESS) || (Status == STATUS_MORE_ENTRIES)) { *bufptr = (LPBYTE) GenericInfoContainer.Buffer; *EntriesRead = GenericInfoContainer.EntriesRead; } return Status; } // LlsServerProductEnumA ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsLocalProductEnumW( LLS_HANDLE Handle, DWORD Level, LPBYTE* bufptr, DWORD PrefMaxLen, LPDWORD EntriesRead, LPDWORD TotalEntries, LPDWORD ResumeHandle ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; GENERIC_INFO_CONTAINER GenericInfoContainer; GENERIC_ENUM_STRUCT InfoStruct; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsLocalProductEnumW\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) return STATUS_INVALID_PARAMETER; GenericInfoContainer.Buffer = NULL; GenericInfoContainer.EntriesRead = 0; InfoStruct.Container = &GenericInfoContainer; InfoStruct.Level = Level; try { Status = LlsrLocalProductEnumW( pLocalHandle->Handle, (PLLS_SERVER_PRODUCT_ENUM_STRUCTW) &InfoStruct, PrefMaxLen, TotalEntries, ResumeHandle ); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } if ((Status == STATUS_SUCCESS) || (Status == STATUS_MORE_ENTRIES)) { *bufptr = (LPBYTE) GenericInfoContainer.Buffer; *EntriesRead = GenericInfoContainer.EntriesRead; } return Status; } // LlsLocalProductEnumW ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsLocalProductEnumA( LLS_HANDLE Handle, DWORD Level, LPBYTE* bufptr, DWORD PrefMaxLen, LPDWORD EntriesRead, LPDWORD TotalEntries, LPDWORD ResumeHandle ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; GENERIC_INFO_CONTAINER GenericInfoContainer; GENERIC_ENUM_STRUCT InfoStruct; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsLocalProductEnumA\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) return STATUS_INVALID_PARAMETER; GenericInfoContainer.Buffer = NULL; GenericInfoContainer.EntriesRead = 0; InfoStruct.Container = &GenericInfoContainer; InfoStruct.Level = Level; try { Status = LlsrLocalProductEnumA( pLocalHandle->Handle, (PLLS_SERVER_PRODUCT_ENUM_STRUCTA) &InfoStruct, PrefMaxLen, TotalEntries, ResumeHandle ); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } if ((Status == STATUS_SUCCESS) || (Status == STATUS_MORE_ENTRIES)) { *bufptr = (LPBYTE) GenericInfoContainer.Buffer; *EntriesRead = GenericInfoContainer.EntriesRead; } return Status; } // LlsLocalProductEnumA ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsLocalProductInfoGetW( IN LLS_HANDLE Handle, IN LPWSTR Product, IN DWORD Level, OUT LPBYTE* bufptr ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsLocalProductInfoGetW\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if ((pLocalHandle == NULL) || (bufptr == NULL)) return STATUS_INVALID_PARAMETER; *bufptr = NULL; try { Status = LlsrLocalProductInfoGetW(pLocalHandle->Handle, Product, Level, (PVOID) bufptr); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } return Status; } // LlsLocalProductInfoGetW ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsLocalProductInfoGetA( IN LLS_HANDLE Handle, IN LPSTR Product, IN DWORD Level, OUT LPBYTE* bufptr ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsLocalProductInfoGetA\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if ((pLocalHandle == NULL) || (bufptr == NULL)) return STATUS_INVALID_PARAMETER; *bufptr = NULL; try { Status = LlsrLocalProductInfoGetA(pLocalHandle->Handle, Product, Level, (PVOID) bufptr); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } return Status; } // LlsLocalProductInfoGetA ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsLocalProductInfoSetW( IN LLS_HANDLE Handle, IN LPWSTR Product, IN DWORD Level, IN LPBYTE bufptr ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsLocalProductInfoSetW\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) return STATUS_INVALID_PARAMETER; try { Status = LlsrLocalProductInfoSetW(pLocalHandle->Handle, Product, Level, (PVOID) bufptr); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } return Status; } // LlsLocalProductInfoSetW ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsLocalProductInfoSetA( IN LLS_HANDLE Handle, IN LPSTR Product, IN DWORD Level, IN LPBYTE bufptr ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsLocalProductInfoSetA\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) return STATUS_INVALID_PARAMETER; try { Status = LlsrLocalProductInfoSetA(pLocalHandle->Handle, Product, Level, (PVOID) bufptr); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } return Status; } // LlsLocalProductInfoSetA #endif // OBSOLETE ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsServiceInfoGetW( IN LLS_HANDLE Handle, IN DWORD Level, OUT LPBYTE* bufptr ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsServiceInfoGetW\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if ((pLocalHandle == NULL) || (bufptr == NULL)) return STATUS_INVALID_PARAMETER; if ( LlsCapabilityIsSupported( Handle, LLS_CAPABILITY_SERVICE_INFO_GETW ) ) { *bufptr = NULL; try { Status = LlsrServiceInfoGetW(pLocalHandle->Handle, Level, (PVOID) bufptr); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } } else if ( 0 != Level ) { Status = STATUS_INVALID_LEVEL; } else { // the target server will blow up if we make the RPC call // in 3.51, the IDL file for the returned structure was incorrect, causing // the ReplicateTo and EnterpriseServer buffers at the server to be freed // instead, get this info from the target machine's registry PLLS_SERVICE_INFO_0W pServiceInfo; pServiceInfo = MIDL_user_allocate( sizeof( *pServiceInfo ) ); if ( NULL == pServiceInfo ) { Status = STATUS_NO_MEMORY; } else { DWORD cbServerName = sizeof( WCHAR ) * ( 3 + MAX_PATH ); ZeroMemory( pServiceInfo, sizeof( *pServiceInfo ) ); pServiceInfo->Version = 5; // we know it's a 3.51 box pServiceInfo->TimeStarted = 0; // don't know, but 3.51 fills in 0 anyway pServiceInfo->Mode = LLS_MODE_ENTERPRISE_SERVER; // we know it's a 3.51 box pServiceInfo->ReplicateTo = MIDL_user_allocate( cbServerName ); pServiceInfo->EnterpriseServer = MIDL_user_allocate( cbServerName ); if ( ( NULL == pServiceInfo->ReplicateTo ) || ( NULL == pServiceInfo->EnterpriseServer ) ) { Status = STATUS_NO_MEMORY; } else { HKEY hKeyLocalMachine; LONG lError; // get parameters from registry lError = RegConnectRegistry( pLocalHandle->szServerName + 2, HKEY_LOCAL_MACHINE, &hKeyLocalMachine ); if ( ERROR_SUCCESS == lError ) { HKEY hKeyParameters; lError = RegOpenKeyEx( hKeyLocalMachine, TEXT( "System\\CurrentControlSet\\Services\\LicenseService\\Parameters" ), 0, KEY_READ, &hKeyParameters ); if ( ERROR_SUCCESS == lError ) { DWORD cbData; // these parameters all default to 0 // (they were initialized to 0 via ZeroMemory(), above) cbData = sizeof( pServiceInfo->ReplicationTime ); lError = RegQueryValueEx( hKeyParameters, TEXT( "ReplicationTime" ), NULL, NULL, (LPBYTE) &pServiceInfo->ReplicationTime, &cbData ); cbData = sizeof( pServiceInfo->ReplicationType ); lError = RegQueryValueEx( hKeyParameters, TEXT( "ReplicationType" ), NULL, NULL, (LPBYTE) &pServiceInfo->ReplicationType, &cbData ); cbData = sizeof( pServiceInfo->UseEnterprise ); lError = RegQueryValueEx( hKeyParameters, TEXT( "UseEnterprise" ), NULL, NULL, (LPBYTE) &pServiceInfo->UseEnterprise, &cbData ); RegCloseKey( hKeyParameters ); lError = ERROR_SUCCESS; } RegCloseKey( hKeyLocalMachine ); } switch ( lError ) { case ERROR_SUCCESS: Status = STATUS_SUCCESS; break; case ERROR_ACCESS_DENIED: Status = STATUS_ACCESS_DENIED; break; default: Status = STATUS_UNSUCCESSFUL; break; } if ( STATUS_SUCCESS == Status ) { // parameters retrieved from registry; only remaining parameters // to be filled in are EnterpriseServer and ReplicateTo TCHAR szDomain[ 1 + MAX_PATH ]; // retrieve the enterprise server EnterpriseServerGet( pLocalHandle->szServerName, pServiceInfo->EnterpriseServer ); // derive ReplicateTo Status = NTDomainGet( pLocalHandle->szServerName, szDomain ); if ( STATUS_ACCESS_DENIED != Status ) { if ( STATUS_SUCCESS == Status ) { NET_API_STATUS netStatus; LPWSTR pszDCName; netStatus = NetGetDCName( NULL, szDomain, (LPBYTE *) &pszDCName ); if ( NERR_Success == netStatus ) { if ( !lstrcmpi( pszDCName, pLocalHandle->szServerName ) ) { // server is primary domain controller; // it replicates to its enterprise server (if any) lstrcpy( pServiceInfo->ReplicateTo, pServiceInfo->EnterpriseServer ); } else { // server is domain member; it replicates to the DC lstrcpy( pServiceInfo->ReplicateTo, pszDCName ); } NetApiBufferFree( pszDCName ); } else { // server had domain but domain has no DC? Status = STATUS_NO_SUCH_DOMAIN; } } else { // server is not in a domain; // it replicates to its enterprise server (if any) lstrcpy( pServiceInfo->ReplicateTo, pServiceInfo->EnterpriseServer ); Status = STATUS_SUCCESS; } } } } } if ( STATUS_SUCCESS != Status ) { if ( NULL != pServiceInfo ) { if ( NULL != pServiceInfo->ReplicateTo ) { MIDL_user_free( pServiceInfo->ReplicateTo ); } if ( NULL != pServiceInfo->EnterpriseServer ) { MIDL_user_free( pServiceInfo->EnterpriseServer ); } MIDL_user_free( pServiceInfo ); } } else { if ( !lstrcmpi( pLocalHandle->szServerName, pServiceInfo->ReplicateTo ) ) { *pServiceInfo->ReplicateTo = TEXT( '\0' ); } if ( !lstrcmpi( pLocalHandle->szServerName, pServiceInfo->EnterpriseServer ) ) { *pServiceInfo->EnterpriseServer = TEXT( '\0' ); } *bufptr = (LPBYTE) pServiceInfo; } } return Status; } // LlsServiceInfoGetW ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsServiceInfoGetA( IN LLS_HANDLE Handle, IN DWORD Level, OUT LPBYTE* bufptr ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsServiceInfoGetA\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if ((pLocalHandle == NULL) || (bufptr == NULL)) return STATUS_INVALID_PARAMETER; *bufptr = NULL; try { Status = LlsrServiceInfoGetA(pLocalHandle->Handle, Level, (PVOID) bufptr); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } return Status; } // LlsServiceInfoGetA ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsServiceInfoSetW( IN LLS_HANDLE Handle, IN DWORD Level, IN LPBYTE bufptr ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsServiceInfoSetW\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) return STATUS_INVALID_PARAMETER; try { Status = LlsrServiceInfoSetW(pLocalHandle->Handle, Level, (PVOID) bufptr); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } if ( ( STATUS_NOT_SUPPORTED == Status ) && ( 0 == Level ) ) { // RPC API is not supported; use the registry instead HKEY hKeyLocalMachine; HKEY hKeyParameters; LONG lError; PLLS_SERVICE_INFO_0W pServiceInfo = (PLLS_SERVICE_INFO_0W) bufptr; LPWSTR pszEnterpriseServer; pszEnterpriseServer = pServiceInfo->EnterpriseServer; // strip leading backslashes from EnterpriseServer if ( !wcsncmp( pszEnterpriseServer, L"\\\\", 2 ) ) { pszEnterpriseServer += 2; } lError = RegConnectRegistry( pLocalHandle->szServerName + 2, HKEY_LOCAL_MACHINE, &hKeyLocalMachine ); if ( ERROR_SUCCESS == lError ) { lError = RegOpenKeyEx( hKeyLocalMachine, TEXT( "System\\CurrentControlSet\\Services\\LicenseService\\Parameters" ), 0, KEY_WRITE, &hKeyParameters ); if ( ERROR_SUCCESS == lError ) { lError = RegSetValueExW( hKeyParameters, L"EnterpriseServer", 0, REG_SZ, (LPBYTE) pszEnterpriseServer, sizeof( *pszEnterpriseServer ) * ( 1 + lstrlenW( pszEnterpriseServer ) ) ); if ( ERROR_SUCCESS == lError ) { lError = RegSetValueEx( hKeyParameters, TEXT( "ReplicationTime" ), 0, REG_DWORD, (LPBYTE) &pServiceInfo->ReplicationTime, sizeof( pServiceInfo->ReplicationTime ) ); if ( ERROR_SUCCESS == lError ) { lError = RegSetValueEx( hKeyParameters, TEXT( "ReplicationType" ), 0, REG_DWORD, (LPBYTE) &pServiceInfo->ReplicationType, sizeof( pServiceInfo->ReplicationType ) ); if ( ERROR_SUCCESS == lError ) { lError = RegSetValueEx( hKeyParameters, TEXT( "UseEnterprise" ), 0, REG_DWORD, (LPBYTE) &pServiceInfo->UseEnterprise, sizeof( pServiceInfo->UseEnterprise ) ); if ( ERROR_SUCCESS == lError ) { Status = STATUS_SUCCESS; } } } } RegCloseKey( hKeyParameters ); } RegCloseKey( hKeyLocalMachine ); } } return Status; } // LlsServiceInfoSetW ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsServiceInfoSetA( IN LLS_HANDLE Handle, IN DWORD Level, IN LPBYTE bufptr ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsServiceInfoSetA\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) return STATUS_INVALID_PARAMETER; try { Status = LlsrServiceInfoSetA(pLocalHandle->Handle, Level, (PVOID) bufptr); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } return Status; } // LlsServiceInfoSetA ///////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////// NTSTATUS LlsReplConnectW( LPTSTR Server, LLS_REPL_HANDLE* Handle ) /*++ Routine Description: Arguments: Return Value: None. --*/ { RPC_STATUS Status; LPTSTR pszUuid = NULL; LPTSTR pszProtocolSequence = NULL; LPTSTR pszNetworkAddress = NULL; LPTSTR pszEndpoint = NULL; LPTSTR pszOptions = NULL; TCHAR pComputer[MAX_COMPUTERNAME_LENGTH + 1]; ULONG Size; #ifdef API_TRACE if (Server == NULL) dprintf(TEXT("LLSRPC.DLL: LlsReplConnectW: \n")); else dprintf(TEXT("LLSRPC.DLL: LlsReplConnectW: %s\n"), Server); #endif // // ** NEW - NT 5.0 ** // // The server name may either be a DNS name or a NetBIOS name. // if (Server == NULL || (Server != NULL && !*Server)) return STATUS_INVALID_PARAMETER; Size = sizeof(pComputer) / sizeof(TCHAR); GetComputerName(pComputer, &Size); pszProtocolSequence = TEXT("ncacn_np"); pszEndpoint = TEXT(LLS_NP_ENDPOINT); pszNetworkAddress = Server; // Compose a string binding Status = RpcStringBindingComposeW(pszUuid, pszProtocolSequence, pszNetworkAddress, pszEndpoint, pszOptions, &pszStringBinding); if(Status) { #if DBG dprintf(TEXT("LLSRPC RpcStringBindingComposeW Failed: 0x%lX\n"), Status); #endif return I_RpcMapWin32Status(Status); } RtlEnterCriticalSection( &g_RpcHandleLock ); // Bind using the created string binding... Status = RpcBindingFromStringBindingW(pszStringBinding, &llsrpc_handle); if(Status) { #if DBG dprintf(TEXT("LLSRPC RpcBindingFromStringBindingW Failed: 0x%lX\n"), Status); #endif if(pszStringBinding != NULL) { RpcStringFree(&pszStringBinding); } if(llsrpc_handle != NULL) { RpcBindingFree(llsrpc_handle); llsrpc_handle = NULL; } RtlLeaveCriticalSection( &g_RpcHandleLock ); return I_RpcMapWin32Status(Status); } try { LlsrReplConnect(Handle, pComputer); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } if(!NT_SUCCESS(Status)) { if(pszStringBinding != NULL) { RpcStringFree(&pszStringBinding); } if(llsrpc_handle != NULL) { RpcBindingFree(llsrpc_handle); llsrpc_handle = NULL; } } RtlLeaveCriticalSection( &g_RpcHandleLock ); return I_RpcMapWin32Status(Status); } // LlsReplConnectW ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsReplClose( PLLS_REPL_HANDLE Handle ) /*++ Routine Description: Arguments: Return Value: None. --*/ { RPC_STATUS Status; NTSTATUS NtStatus = STATUS_SUCCESS; try { NtStatus = LlsrReplClose(Handle); } except (TRUE) { NtStatus = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), NtStatus); #endif } try { Status = RpcStringFree(&pszStringBinding); if (Status ) { NtStatus = I_RpcMapWin32Status(Status); #if DBG dprintf(TEXT("LLSRPC.DLL: LlsClose - RpcStringFree returned: 0x%lX\n"), NtStatus); #endif } Status = RpcBindingFree(&llsrpc_handle); if (Status ) { NtStatus = I_RpcMapWin32Status(Status); #if DBG dprintf(TEXT("LLSRPC.DLL: LlsClose - RpcBindingFree returned: 0x%lX\n"), NtStatus); #endif } } except (TRUE) { NtStatus = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), NtStatus); #endif } return NtStatus; } // LlsClose ///////////////////////////////////////////////////////////////////////// NTSTATUS LlsReplicationRequestW( IN LLS_REPL_HANDLE Handle, IN DWORD Version, IN OUT PREPL_REQUEST Request ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; try { Status = LlsrReplicationRequestW(Handle, Version, Request); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } return Status; } // LlsReplicationRequestW ///////////////////////////////////////////////////////////////////////// NTSTATUS LlsReplicationServerAddW( IN LLS_REPL_HANDLE Handle, IN ULONG NumRecords, IN PREPL_SERVER_RECORD Servers ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; try { Status = LlsrReplicationServerAddW(Handle, NumRecords, Servers); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } return Status; } // LlsReplicationServerAddW ///////////////////////////////////////////////////////////////////////// NTSTATUS LlsReplicationServerServiceAddW( IN LLS_REPL_HANDLE Handle, IN ULONG NumRecords, IN PREPL_SERVER_SERVICE_RECORD ServerServices ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; try { Status = LlsrReplicationServerServiceAddW(Handle, NumRecords, ServerServices); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } return Status; } // LlsReplicationServerServiceAddW ///////////////////////////////////////////////////////////////////////// NTSTATUS LlsReplicationServiceAddW( IN LLS_REPL_HANDLE Handle, IN ULONG NumRecords, IN PREPL_SERVICE_RECORD Services ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; try { Status = LlsrReplicationServiceAddW(Handle, NumRecords, Services); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } return Status; } // LlsReplicationServiceAddW ///////////////////////////////////////////////////////////////////////// NTSTATUS LlsReplicationUserAddW( IN LLS_REPL_HANDLE Handle, IN ULONG NumRecords, IN PREPL_USER_RECORD_0 Users ) /*++ Routine Description: Arguments: Return Value: None. --*/ { NTSTATUS Status; try { Status = LlsrReplicationUserAddW(Handle, NumRecords, Users); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } return Status; } // LlsReplicationUserAddW ///////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsProductSecurityGetW( LLS_HANDLE Handle, LPWSTR Product, LPBOOL pIsSecure ) /*++ Routine Description: Retrieve the "security" of a product. A product is deemed secure iff it requires a secure certificate. In such a case, licenses for the product may not be entered via the Honesty ("enter the number of licenses you purchased") method. Arguments: Handle (LLS_HANDLE) An open LLS handle to the target license server. Product (LPWSTR) The name of the product ("DisplayName") for which to receive the security. pIsSecure (LPBOOL) On return, and if successful, indicates whether the product is secure. Return Value: STATUS_SUCCESS or NTSTATUS error code. --*/ { NTSTATUS Status; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsProductSecurityGetW\n")); #endif if ( !LlsCapabilityIsSupported( Handle, LLS_CAPABILITY_SECURE_CERTIFICATES ) ) { return STATUS_NOT_SUPPORTED; } pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) return STATUS_INVALID_PARAMETER; try { Status = LlsrProductSecurityGetW( pLocalHandle->Handle, Product, pIsSecure ); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } return Status; } // LlsProductSecurityGetW ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsProductSecurityGetA( LLS_HANDLE Handle, LPSTR Product, LPBOOL pIsSecure ) /*++ Routine Description: Retrieve the "security" of a product. A product is deemed secure iff it requires a secure certificate. In such a case, licenses for the product may not be entered via the Honesty ("enter the number of licenses you purchased") method. NOTE: Not yet implemented. Use LlsProductSecurityGetW(). Arguments: Handle (LLS_HANDLE) An open LLS handle to the target license server. Product (LPSTR) The name of the product ("DisplayName") for which to receive the security. pIsSecure (LPBOOL) On return, and if successful, indicates whether the product is secure. Return Value: STATUS_NOT_SUPPORTED. --*/ { #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsProductSecurityGetA\n")); #endif return STATUS_NOT_SUPPORTED; } // LlsProductSecurityGetA ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsProductSecuritySetW( LLS_HANDLE Handle, LPWSTR Product ) /*++ Routine Description: Flags the given product as secure. A product is deemed secure iff it requires a secure certificate. In such a case, licenses for the product may not be entered via the Honesty ("enter the number of licenses you purchased") method. This designation is not reversible and is propagated up the replication tree. Arguments: Handle (LLS_HANDLE) An open LLS handle to the target license server. Product (LPWSTR) The name of the product ("DisplayName") for which to activate security. Return Value: STATUS_SUCCESS or NTSTATUS error code. --*/ { NTSTATUS Status; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsProductSecuritySetW\n")); #endif if ( !LlsCapabilityIsSupported( Handle, LLS_CAPABILITY_SECURE_CERTIFICATES ) ) { return STATUS_NOT_SUPPORTED; } pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) return STATUS_INVALID_PARAMETER; try { Status = LlsrProductSecuritySetW( pLocalHandle->Handle, Product ); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } return Status; } // LlsProductSecuritySetW ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsProductSecuritySetA( LLS_HANDLE Handle, LPSTR Product ) /*++ Routine Description: Flags the given product as secure. A product is deemed secure iff it requires a secure certificate. In such a case, licenses for the product may not be entered via the Honesty ("enter the number of licenses you purchased") method. This designation is not reversible and is propagated up the replication tree. NOTE: Not yet implemented. Use LlsProductSecuritySetW(). Arguments: Handle (LLS_HANDLE) An open LLS handle to the target license server. Product (LPSTR) The name of the product ("DisplayName") for which to activate security. Return Value: STATUS_NOT_SUPPORTED. --*/ { #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsProductSecuritySetA\n")); #endif return STATUS_NOT_SUPPORTED; } // LlsProductSecuritySetA ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsProductLicensesGetW( LLS_HANDLE Handle, LPWSTR Product, DWORD Mode, LPDWORD pQuantity ) /*++ Routine Description: Returns the number of licenses installed on the target machine for use in the given mode. Arguments: Handle (LLS_HANDLE) An open LLS handle to the target license server. Product (LPWSTR) The name of the product for which to tally licenses. Mode (DWORD) Licensing mode for which to tally the licenses. pQuantity (LPDWORD) On return (and if successful), holds the total number of licenses for use by the given product in the given license mode. Return Value: STATUS_SUCCESS or NTSTATUS error code. --*/ { NTSTATUS Status; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsProductLicensesGetW\n")); #endif if ( !LlsCapabilityIsSupported( Handle, LLS_CAPABILITY_SECURE_CERTIFICATES ) ) { return STATUS_NOT_SUPPORTED; } pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) return STATUS_INVALID_PARAMETER; try { Status = LlsrProductLicensesGetW( pLocalHandle->Handle, Product, Mode, pQuantity ); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } return Status; } // LlsProductLicensesGetW ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsProductLicensesGetA( LLS_HANDLE Handle, LPSTR Product, DWORD Mode, LPDWORD pQuantity ) /*++ Routine Description: Returns the number of licenses installed on the target machine for use in the given mode. NOTE: Not yet implemented. Use LlsProductLicensesGetW(). Arguments: Handle (LLS_HANDLE) An open LLS handle to the target license server. Product (LPSTR) The name of the product for which to tally licenses. Mode (DWORD) Licensing mode for which to tally the licenses. pQuantity (LPDWORD) On return (and if successful), holds the total number of licenses for use by the given product in the given license mode. Return Value: STATUS_NOT_SUPPORTED. --*/ { #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsProductLicensesGetA\n")); #endif return STATUS_NOT_SUPPORTED; } // LlsProductLicensesGetA #ifdef OBSOLETE ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsCertificateClaimEnumW( LLS_HANDLE Handle, DWORD LicenseLevel, LPBYTE pLicenseInfo, DWORD TargetLevel, LPBYTE * ppTargets, LPDWORD pNumTargets ) /*++ Routine Description: Enumerates the servers on which a given secure certificate is installed. This function is normally invoked when an attempt to add licenses from a certificate is denied. Arguments: Handle (LLS_HANDLE) An open LLS handle to the target license server. LicenseLevel (DWORD) The level of the license structure pointed to by pLicenseInfo. pLicenseInfo (LPBYTE) Points to a LLS_LICENSE_INFO_X structure, where X is LicenseLevel. This license structure describes a license for which the certificate targets are requested. TargetLevel (DWORD) The level of the target structure desired. ppTargets (LPBYTE *) On return (and if successful), holds a PLLS_EX_CERTIFICATE_CLAIM_X, where X is TargetLevel. This array of structures describes the location of all installations of licenses from the given certificate. pNumTargets (LPDWORD) On return (and if successful), holds the number of structures pointed to by ppTargets. Return Value: STATUS_SUCCESS or NTSTATUS error code. --*/ { NTSTATUS Status; GENERIC_INFO_CONTAINER GenericInfoContainer; GENERIC_ENUM_STRUCT InfoStruct; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsCertificateClaimEnumW\n")); #endif if ( !LlsCapabilityIsSupported( Handle, LLS_CAPABILITY_SECURE_CERTIFICATES ) ) { return STATUS_NOT_SUPPORTED; } pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) return STATUS_INVALID_PARAMETER; GenericInfoContainer.Buffer = NULL; GenericInfoContainer.EntriesRead = 0; InfoStruct.Container = &GenericInfoContainer; InfoStruct.Level = TargetLevel; try { Status = LlsrCertificateClaimEnumW( pLocalHandle->Handle, LicenseLevel, (LPVOID) pLicenseInfo, (PLLS_CERTIFICATE_CLAIM_ENUM_STRUCTW) &InfoStruct ); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } if (Status == STATUS_SUCCESS) { *ppTargets = (LPBYTE) GenericInfoContainer.Buffer; *pNumTargets = GenericInfoContainer.EntriesRead; } return Status; } // LlsCertificateClaimEnumW ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsCertificateClaimEnumA( LLS_HANDLE Handle, DWORD LicenseLevel, LPBYTE pLicenseInfo, DWORD TargetLevel, LPBYTE * ppTargets, LPDWORD pNumTargets ) /*++ Routine Description: Enumerates the servers on which a given secure certificate is installed. This function is normally invoked when an attempt to add licenses from a certificate is denied. NOTE: Not yet implemented. Use LlsCertificateClaimEnumW(). Arguments: Handle (LLS_HANDLE) An open LLS handle to the target license server. LicenseLevel (DWORD) The level of the license structure pointed to by pLicenseInfo. pLicenseInfo (LPBYTE) Points to a LLS_LICENSE_INFO_X structure, where X is LicenseLevel. This license structure describes a license for which the certificate targets are requested. TargetLevel (DWORD) The level of the target structure desired. ppTargets (LPBYTE *) On return (and if successful), holds a PLLS_EX_CERTIFICATE_CLAIM_X, where X is TargetLevel. This array of structures describes the location of all installations of licenses from the given certificate. pNumTargets (LPDWORD) On return (and if successful), holds the number of structures pointed to by ppTargets. Return Value: STATUS_NOT_SUPPORTED. --*/ { #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsCertificateClaimEnumA\n")); #endif return STATUS_NOT_SUPPORTED; } // LlsCertificateClaimEnumA #endif // OBSOLETE ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsCertificateClaimAddCheckW( LLS_HANDLE Handle, DWORD LicenseLevel, LPBYTE pLicenseInfo, LPBOOL pbMayInstall ) /*++ Routine Description: Verify that no more licenses from a given certificate are installed in a licensing enterprise than are allowed by the certificate. Arguments: Handle (LLS_HANDLE) An open LLS handle to the target license server. LicenseLevel (DWORD) The level of the license structure pointed to by pLicenseInfo. pLicenseInfo (LPBYTE) Points to a LLS_LICENSE_INFO_X structure, where X is LicenseLevel. This license structure describes the license wished to add. pbMayInstall (LPBOOL) On return (and if successful), indicates whether the certificate may be legally installed. Return Value: STATUS_SUCCESS or NTSTATUS error code. --*/ { NTSTATUS Status; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsCertificateClaimAddCheckW\n")); #endif if ( !LlsCapabilityIsSupported( Handle, LLS_CAPABILITY_SECURE_CERTIFICATES ) ) { return STATUS_NOT_SUPPORTED; } pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) return STATUS_INVALID_PARAMETER; try { Status = LlsrCertificateClaimAddCheckW( pLocalHandle->Handle, LicenseLevel, (LPVOID) pLicenseInfo, pbMayInstall ); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } return Status; } // LlsCertificateClaimAddCheckW ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsCertificateClaimAddCheckA( IN LLS_HANDLE Handle, IN DWORD LicenseLevel, IN LPBYTE pLicenseInfo, OUT LPBOOL pbMayInstall ) /*++ Routine Description: Verify that no more licenses from a given certificate are installed in a licensing enterprise than are allowed by the certificate. NOTE: Not yet implemented. Use LlsCertificateClaimAddCheckW(). Arguments: Handle (LLS_HANDLE) An open LLS handle to the target license server. LicenseLevel (DWORD) The level of the license structure pointed to by pLicenseInfo. pLicenseInfo (LPBYTE) Points to a LLS_LICENSE_INFO_X structure, where X is LicenseLevel. This license structure describes the license wished to add. pbMayInstall (LPBOOL) On return (and if successful), indicates whether the certificate may be legally installed. Return Value: STATUS_NOT_SUPPORTED. --*/ { #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsCertificateClaimAddCheckA\n")); #endif return STATUS_NOT_SUPPORTED; } // LlsCertificateClaimAddCheckA ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsCertificateClaimAddW( LLS_HANDLE Handle, LPWSTR ServerName, DWORD LicenseLevel, LPBYTE pLicenseInfo ) /*++ Routine Description: Declare a number of licenses from a given certificate as being installed on the target machine. Arguments: Handle (LLS_HANDLE) An open LLS handle to the target license server. ServerName (LPWSTR) Name of the server on which the licenses are installed. LicenseLevel (DWORD) The level of the license structure pointed to by pLicenseInfo. pLicenseInfo (LPBYTE) Points to a LLS_LICENSE_INFO_X structure, where X is LicenseLevel. This license structure describes the license added. Return Value: STATUS_SUCCESS or NTSTATUS error code. --*/ { NTSTATUS Status; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsCertificateClaimAddW\n")); #endif if ( !LlsCapabilityIsSupported( Handle, LLS_CAPABILITY_SECURE_CERTIFICATES ) ) { return STATUS_NOT_SUPPORTED; } pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) return STATUS_INVALID_PARAMETER; try { Status = LlsrCertificateClaimAddW( pLocalHandle->Handle, ServerName, LicenseLevel, (LPVOID) pLicenseInfo ); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } return Status; } // LlsCertificateClaimAddW ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsCertificateClaimAddA( LLS_HANDLE Handle, LPSTR ServerName, DWORD LicenseLevel, LPBYTE pLicenseInfo ) /*++ Routine Description: Declare a number of licenses from a given certificate as being installed on the target machine. NOTE: Not yet implemented. Use LlsCertificateClaimAddW(). Arguments: Handle (LLS_HANDLE) An open LLS handle to the target license server. ServerName (LPWSTR) Name of the server on which the licenses are installed. LicenseLevel (DWORD) The level of the license structure pointed to by pLicenseInfo. pLicenseInfo (LPBYTE) Points to a LLS_LICENSE_INFO_X structure, where X is LicenseLevel. This license structure describes the license added. Return Value: STATUS_NOT_SUPPORTED. --*/ { #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsCertificateClaimAddA\n")); #endif return STATUS_NOT_SUPPORTED; } // LlsCertificateClaimAddA ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsReplicationCertDbAddW( LLS_REPL_HANDLE Handle, DWORD Level, LPVOID Certificates ) /*++ Routine Description: Called as an optional part of replication, this function replicates the contents of the remote certificate database. Arguments: Handle (LLS_REPL_HANDLE) An open replication handle to the target server. Level (DWORD) Level of replication information sent. Certificates (LPVOID) Replicated certificate information. Return Value: STATUS_SUCCESS or NTSTATUS error code. --*/ { NTSTATUS Status; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsReplicationCertDbAddW\n")); #endif try { Status = LlsrReplicationCertDbAddW( Handle, Level, Certificates ); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } return Status; } // LlsReplicationCertDbAddW ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsReplicationProductSecurityAddW( LLS_REPL_HANDLE Handle, DWORD Level, LPVOID SecureProducts ) /*++ Routine Description: Called as an optional part of replication, this function replicates the list of products which require secure certificates. Arguments: Handle (LLS_REPL_HANDLE) An open replication handle to the target server. Level (DWORD) Level of the product security information. SecureProducts (LPVOID) Replicated secure product information. Return Value: STATUS_SUCCESS or NTSTATUS error code. --*/ { NTSTATUS Status; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsReplicationProductSecurityAddW\n")); #endif try { Status = LlsrReplicationProductSecurityAddW( Handle, Level, SecureProducts ); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } return Status; } // LlsReplicationProductSecurityAddW ///////////////////////////////////////////////////////////////////////// NTSTATUS NTAPI LlsReplicationUserAddExW( LLS_REPL_HANDLE Handle, DWORD Level, LPVOID Users ) /*++ Routine Description: Replacement for LlsReplicationUserAddW(). (This function, unlike its counterpart, supports structure levels.) This function replicates the user list. Arguments: Handle (LLS_REPL_HANDLE) An open replication handle to the target server. Level (DWORD) Level of the user information. Users (LPVOID) Replicated user information. Return Value: STATUS_SUCCESS or NTSTATUS error code. --*/ { NTSTATUS Status; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsReplicationUserAddExW\n")); #endif if ( (0 != Level) && (1 != Level) ) return STATUS_INVALID_LEVEL; try { Status = LlsrReplicationUserAddExW( Handle, Level, Users ); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } return Status; } // LlsReplicationUserAddExW ///////////////////////////////////////////////////////////////////////// BOOL NTAPI LlsCapabilityIsSupported( LLS_HANDLE Handle, DWORD Capability ) /*++ Routine Description: Determine whether the target license server supports an arbitrary function. Arguments: Handle (LLS_HANDLE) An open LLS handle to the target license server. Capability (DWORD) The capability number to check for, 0 <= Capability < LLS_CAPABILITY_MAX. Return Value: TRUE (supports the capability) or FALSE (does not). --*/ { BOOL bIsSupported = FALSE; PLOCAL_HANDLE pLocalHandle; DWORD dwCapByte; DWORD dwCapBit; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsCapabilityIsSupported\n")); #endif if ( ( NULL != Handle ) && ( Capability < LLS_CAPABILITY_MAX ) ) { pLocalHandle = (PLOCAL_HANDLE) Handle; dwCapByte = Capability / 8; dwCapBit = Capability - 8 * dwCapByte; if ( 1 & ( pLocalHandle->Capabilities[ dwCapByte ] >> dwCapBit ) ) { bIsSupported = TRUE; } } return bIsSupported; } // LlsCapabilityIsSupported NTSTATUS NTAPI LlsLocalServiceEnumW( LLS_HANDLE Handle, DWORD Level, LPBYTE* bufptr, DWORD PrefMaxLen, LPDWORD EntriesRead, LPDWORD TotalEntries, LPDWORD ResumeHandle ) { NTSTATUS Status; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsLocalServiceEnumW\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) { Status = STATUS_INVALID_PARAMETER; } else if ( LlsCapabilityIsSupported( Handle, LLS_CAPABILITY_LOCAL_SERVICE_API ) ) { GENERIC_INFO_CONTAINER GenericInfoContainer; GENERIC_ENUM_STRUCT InfoStruct; GenericInfoContainer.Buffer = NULL; GenericInfoContainer.EntriesRead = 0; InfoStruct.Container = &GenericInfoContainer; InfoStruct.Level = Level; try { Status = LlsrLocalServiceEnumW( pLocalHandle->Handle, (PLLS_LOCAL_SERVICE_ENUM_STRUCTW) &InfoStruct, PrefMaxLen, TotalEntries, ResumeHandle ); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } if ((Status == STATUS_SUCCESS) || (Status == STATUS_MORE_ENTRIES)) { *bufptr = (LPBYTE) GenericInfoContainer.Buffer; *EntriesRead = GenericInfoContainer.EntriesRead; } } else if ( 0 != Level ) { Status = STATUS_INVALID_LEVEL; } else { PLLS_LOCAL_SERVICE_INFO_0 pLocalServices = NULL; DWORD cEntriesRead = 0; LONG lError; HKEY hKeyLocalMachine; lError = RegConnectRegistry( pLocalHandle->szServerName, HKEY_LOCAL_MACHINE, &hKeyLocalMachine ); if ( ERROR_SUCCESS == lError ) { HKEY hKeyLicenseInfo; lError = RegOpenKeyEx( hKeyLocalMachine, REG_KEY_LICENSE, 0, KEY_READ, &hKeyLicenseInfo ); if ( ERROR_SUCCESS == lError ) { const DWORD cbBufferSize = 0x4000; // fudge; we ignore MaxPrefLen and allocate a 16k buffer // this is because when we restart an enumeration, we don't know how // many items we have left (we could do it, but it'd be slow) // this is only for 3.51 boxes, anyway, and this buffer will hold // about 500 local service entries (plenty!) // this also keeps us from having to keep the registry key open // across function calls pLocalServices = MIDL_user_allocate( cbBufferSize ); if ( NULL == pLocalServices ) { lError = ERROR_OUTOFMEMORY; } else { DWORD iSubKey; TCHAR szKeyName[ 128 ]; // read all the services installed on this machine for ( iSubKey=0, cEntriesRead=0; ( ERROR_SUCCESS == lError ) && ( ( cEntriesRead + 1 ) * sizeof( *pLocalServices ) < cbBufferSize ); iSubKey++ ) { lError = RegEnumKey( hKeyLicenseInfo, iSubKey, szKeyName, sizeof( szKeyName ) / sizeof( *szKeyName ) ); if ( ERROR_SUCCESS == lError ) { HKEY hKeyService; lError = RegOpenKeyEx( hKeyLicenseInfo, szKeyName, 0, KEY_READ, &hKeyService ); if ( ERROR_SUCCESS == lError ) { DWORD cbData; cbData = sizeof( pLocalServices[ cEntriesRead ].Mode ); lError = RegQueryValueEx( hKeyService, REG_VALUE_MODE, NULL, NULL, (LPBYTE) &pLocalServices[ cEntriesRead ].Mode, &cbData ); if ( ERROR_SUCCESS == lError ) { cbData = sizeof( pLocalServices[ cEntriesRead ].FlipAllow ); lError = RegQueryValueEx( hKeyService, REG_VALUE_FLIP, NULL, NULL, (LPBYTE) &pLocalServices[ cEntriesRead ].FlipAllow, &cbData ); if ( ERROR_SUCCESS == lError ) { cbData = sizeof( pLocalServices[ cEntriesRead ].ConcurrentLimit ); lError = RegQueryValueEx( hKeyService, REG_VALUE_LIMIT, NULL, NULL, (LPBYTE) &pLocalServices[ cEntriesRead ].ConcurrentLimit, &cbData ); if ( ERROR_SUCCESS == lError ) { DWORD cbKeyName; DWORD cbDisplayName; DWORD cbFamilyDisplayName; cbData = sizeof( pLocalServices[ cEntriesRead ].HighMark ); lError = RegQueryValueEx( hKeyService, REG_VALUE_HIGHMARK, NULL, NULL, (LPBYTE) &pLocalServices[ cEntriesRead ].HighMark, &cbData ); if ( ERROR_SUCCESS != lError ) { pLocalServices[ cEntriesRead ].HighMark = 0; lError = ERROR_SUCCESS; } if ( ( ERROR_SUCCESS == RegQueryValueEx( hKeyService, REG_VALUE_NAME, NULL, NULL, NULL, &cbDisplayName ) ) && ( ERROR_SUCCESS == RegQueryValueEx( hKeyService, REG_VALUE_FAMILY, NULL, NULL, NULL, &cbFamilyDisplayName ) ) ) { cbKeyName = sizeof( *szKeyName ) * ( 1 + lstrlen( szKeyName ) ); pLocalServices[ cEntriesRead ].KeyName = MIDL_user_allocate( cbKeyName ); if ( NULL == pLocalServices[ cEntriesRead ].KeyName ) { lError = ERROR_OUTOFMEMORY; } else { lstrcpy( pLocalServices[ cEntriesRead ].KeyName, szKeyName ); pLocalServices[ cEntriesRead ].DisplayName = MIDL_user_allocate( cbDisplayName ); if ( NULL == pLocalServices[ cEntriesRead ].DisplayName ) { lError = ERROR_OUTOFMEMORY; } else { lError = RegQueryValueEx( hKeyService, REG_VALUE_NAME, NULL, NULL, (LPBYTE) pLocalServices[ cEntriesRead ].DisplayName, &cbDisplayName ); if ( ERROR_SUCCESS == lError ) { pLocalServices[ cEntriesRead ].FamilyDisplayName = MIDL_user_allocate( cbFamilyDisplayName ); if ( NULL == pLocalServices[ cEntriesRead ].FamilyDisplayName ) { lError = ERROR_OUTOFMEMORY; } else { lError = RegQueryValueEx( hKeyService, REG_VALUE_FAMILY, NULL, NULL, (LPBYTE) pLocalServices[ cEntriesRead ].FamilyDisplayName, &cbFamilyDisplayName ); if ( ERROR_SUCCESS != lError ) { MIDL_user_free( pLocalServices[ cEntriesRead ].FamilyDisplayName ); } } } if ( ERROR_SUCCESS != lError ) { MIDL_user_free( pLocalServices[ cEntriesRead ].DisplayName ); } } if ( ERROR_SUCCESS != lError ) { MIDL_user_free( pLocalServices[ cEntriesRead ].KeyName ); } else { // all data for this service was retrieved! cEntriesRead++; } } } } } } RegCloseKey( hKeyService ); } if ( ERROR_OUTOFMEMORY != lError ) { // continue enumeration... lError = ERROR_SUCCESS; } } } } RegCloseKey( hKeyLicenseInfo ); } RegCloseKey( hKeyLocalMachine ); } switch ( lError ) { case ERROR_SUCCESS: case ERROR_NO_MORE_ITEMS: Status = STATUS_SUCCESS; break; case ERROR_ACCESS_DENIED: Status = STATUS_ACCESS_DENIED; break; case ERROR_OUTOFMEMORY: Status = STATUS_NO_MEMORY; break; case ERROR_FILE_NOT_FOUND: case ERROR_PATH_NOT_FOUND: Status = STATUS_NOT_FOUND; break; default: Status = STATUS_UNSUCCESSFUL; break; } if ( STATUS_SUCCESS != Status ) { // free all of our allocations DWORD i; for ( i=0; i < cEntriesRead; i++ ) { MIDL_user_free( pLocalServices[ i ].KeyName ); MIDL_user_free( pLocalServices[ i ].DisplayName ); MIDL_user_free( pLocalServices[ i ].FamilyDisplayName ); } MIDL_user_free( pLocalServices ); } else { // success! return the array of services. *bufptr = (LPBYTE) pLocalServices; *EntriesRead = cEntriesRead; *TotalEntries = cEntriesRead; *ResumeHandle = 0; } } return Status; } NTSTATUS NTAPI LlsLocalServiceEnumA( LLS_HANDLE Handle, DWORD Level, LPBYTE* bufptr, DWORD PrefMaxLen, LPDWORD EntriesRead, LPDWORD TotalEntries, LPDWORD ResumeHandle ) { NTSTATUS Status; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsLocalServiceEnumA\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) { Status = STATUS_INVALID_PARAMETER; } else if ( LlsCapabilityIsSupported( Handle, LLS_CAPABILITY_LOCAL_SERVICE_API ) ) { GENERIC_INFO_CONTAINER GenericInfoContainer; GENERIC_ENUM_STRUCT InfoStruct; GenericInfoContainer.Buffer = NULL; GenericInfoContainer.EntriesRead = 0; InfoStruct.Container = &GenericInfoContainer; InfoStruct.Level = Level; try { Status = LlsrLocalServiceEnumA( pLocalHandle->Handle, (PLLS_LOCAL_SERVICE_ENUM_STRUCTA) &InfoStruct, PrefMaxLen, TotalEntries, ResumeHandle ); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } if ((Status == STATUS_SUCCESS) || (Status == STATUS_MORE_ENTRIES)) { *bufptr = (LPBYTE) GenericInfoContainer.Buffer; *EntriesRead = GenericInfoContainer.EntriesRead; } } else { Status = STATUS_NOT_SUPPORTED; } return Status; } #ifdef OBSOLETE NTSTATUS NTAPI LlsLocalServiceAddW( LLS_HANDLE Handle, DWORD Level, LPBYTE bufptr ) { NTSTATUS Status; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsLocalServiceAddW\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) { Status = STATUS_INVALID_PARAMETER; } else if ( LlsCapabilityIsSupported( Handle, LLS_CAPABILITY_LOCAL_SERVICE_API ) ) { try { Status = LlsrLocalServiceAddW( pLocalHandle->Handle, Level, (PLLS_LOCAL_SERVICE_INFOW) bufptr ); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } } else if ( 0 != Level ) { Status = STATUS_INVALID_LEVEL; } else if ( ( NULL == ((PLLS_LOCAL_SERVICE_INFO_0W) bufptr)->KeyName ) || ( NULL == ((PLLS_LOCAL_SERVICE_INFO_0W) bufptr)->DisplayName ) || ( NULL == ((PLLS_LOCAL_SERVICE_INFO_0W) bufptr)->FamilyDisplayName ) ) { Status = STATUS_INVALID_PARAMETER; } else { PLLS_LOCAL_SERVICE_INFO_0W LocalServiceInfo; LONG lError; HKEY hKeyLocalMachine; LocalServiceInfo = (PLLS_LOCAL_SERVICE_INFO_0W) bufptr; lError = RegConnectRegistry( pLocalHandle->szServerName, HKEY_LOCAL_MACHINE, &hKeyLocalMachine ); if ( ERROR_SUCCESS == lError ) { HKEY hKeyLicenseInfo; lError = RegOpenKeyEx( hKeyLocalMachine, TEXT( "System\\CurrentControlSet\\Services\\LicenseInfo" ), 0, KEY_WRITE, &hKeyLicenseInfo ); if ( ERROR_SUCCESS == lError ) { HKEY hKeyService; DWORD dwDisposition; // create key lError = RegCreateKeyEx( hKeyLicenseInfo, LocalServiceInfo->KeyName, 0, NULL, 0, KEY_WRITE, NULL, &hKeyService, &dwDisposition ); if ( ERROR_SUCCESS == lError ) { // set DisplayName lError = RegSetValueEx( hKeyService, TEXT( "DisplayName" ), 0, REG_SZ, (LPBYTE) LocalServiceInfo->DisplayName, sizeof( *LocalServiceInfo->DisplayName ) * ( 1 + lstrlen( LocalServiceInfo->DisplayName ) ) ); if ( ERROR_SUCCESS == lError ) { // set FamilyDisplayName lError = RegSetValueEx( hKeyService, TEXT( "FamilyDisplayName" ), 0, REG_SZ, (LPBYTE) LocalServiceInfo->FamilyDisplayName, sizeof( *LocalServiceInfo->FamilyDisplayName ) * ( 1 + lstrlen( LocalServiceInfo->FamilyDisplayName ) ) ); } RegCloseKey( hKeyService ); } RegCloseKey( hKeyLicenseInfo ); } RegCloseKey( hKeyLocalMachine ); } switch ( lError ) { case ERROR_SUCCESS: Status = STATUS_SUCCESS; break; case ERROR_FILE_NOT_FOUND: case ERROR_PATH_NOT_FOUND: Status = STATUS_OBJECT_NAME_NOT_FOUND; break; case ERROR_ACCESS_DENIED: Status = STATUS_ACCESS_DENIED; break; default: Status = STATUS_UNSUCCESSFUL; break; } if ( STATUS_SUCCESS == Status ) { // set remaining items Status = LlsLocalServiceInfoSetW( Handle, LocalServiceInfo->KeyName, Level, bufptr ); } } return Status; } NTSTATUS NTAPI LlsLocalServiceAddA( LLS_HANDLE Handle, DWORD Level, LPBYTE bufptr ) { NTSTATUS Status; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsLocalServiceAddA\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) { Status = STATUS_INVALID_PARAMETER; } else if ( LlsCapabilityIsSupported( Handle, LLS_CAPABILITY_LOCAL_SERVICE_API ) ) { try { Status = LlsrLocalServiceAddA( pLocalHandle->Handle, Level, (PLLS_LOCAL_SERVICE_INFOA) bufptr ); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } } else { Status = STATUS_NOT_SUPPORTED; } return Status; } #endif // OBSOLETE NTSTATUS NTAPI LlsLocalServiceInfoSetW( LLS_HANDLE Handle, LPWSTR KeyName, DWORD Level, LPBYTE bufptr ) { NTSTATUS Status; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsLocalServiceInfoSetW\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) { Status = STATUS_INVALID_PARAMETER; } else if ( LlsCapabilityIsSupported( Handle, LLS_CAPABILITY_LOCAL_SERVICE_API ) ) { try { Status = LlsrLocalServiceInfoSetW( pLocalHandle->Handle, KeyName, Level, (PLLS_LOCAL_SERVICE_INFOW) bufptr ); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } } else if ( 0 != Level ) { Status = STATUS_INVALID_LEVEL; } else if ( NULL == KeyName ) { Status = STATUS_INVALID_PARAMETER; } else { LONG lError; HKEY hKeyLocalMachine; lError = RegConnectRegistry( pLocalHandle->szServerName, HKEY_LOCAL_MACHINE, &hKeyLocalMachine ); if ( ERROR_SUCCESS == lError ) { HKEY hKeyLicenseInfo; lError = RegOpenKeyEx( hKeyLocalMachine, REG_KEY_LICENSE, 0, KEY_WRITE, &hKeyLicenseInfo ); if ( ERROR_SUCCESS == lError ) { HKEY hKeyService; PLLS_LOCAL_SERVICE_INFO_0W LocalServiceInfo; LocalServiceInfo = (PLLS_LOCAL_SERVICE_INFO_0W) bufptr; lError = RegOpenKeyEx( hKeyLicenseInfo, KeyName, 0, KEY_WRITE, &hKeyService ); if ( ERROR_SUCCESS == lError ) { // set Mode lError = RegSetValueEx( hKeyService, REG_VALUE_MODE, 0, REG_DWORD, (LPBYTE) &LocalServiceInfo->Mode, sizeof( LocalServiceInfo->Mode ) ); if ( ERROR_SUCCESS == lError ) { // set FlipAllow lError = RegSetValueEx( hKeyService, REG_VALUE_FLIP, 0, REG_DWORD, (LPBYTE) &LocalServiceInfo->FlipAllow, sizeof( LocalServiceInfo->FlipAllow ) ); if ( ERROR_SUCCESS == lError ) { // set ConcurrentLimit lError = RegSetValueEx( hKeyService, REG_VALUE_LIMIT, 0, REG_DWORD, (LPBYTE) &LocalServiceInfo->ConcurrentLimit, sizeof( LocalServiceInfo->ConcurrentLimit ) ); } } RegCloseKey( hKeyService ); } RegCloseKey( hKeyLicenseInfo ); } RegCloseKey( hKeyLocalMachine ); } switch ( lError ) { case ERROR_SUCCESS: Status = STATUS_SUCCESS; break; case ERROR_FILE_NOT_FOUND: case ERROR_PATH_NOT_FOUND: Status = STATUS_OBJECT_NAME_NOT_FOUND; break; case ERROR_ACCESS_DENIED: Status = STATUS_ACCESS_DENIED; break; default: Status = STATUS_UNSUCCESSFUL; break; } } return Status; } NTSTATUS NTAPI LlsLocalServiceInfoSetA( LLS_HANDLE Handle, LPSTR KeyName, DWORD Level, LPBYTE bufptr ) { NTSTATUS Status; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsLocalServiceInfoSetA\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) { Status = STATUS_INVALID_PARAMETER; } else if ( LlsCapabilityIsSupported( Handle, LLS_CAPABILITY_LOCAL_SERVICE_API ) ) { try { Status = LlsrLocalServiceInfoSetA( pLocalHandle->Handle, KeyName, Level, (PLLS_LOCAL_SERVICE_INFOA) bufptr ); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } } else { Status = STATUS_NOT_SUPPORTED; } return Status; } NTSTATUS NTAPI LlsLocalServiceInfoGetW( LLS_HANDLE Handle, LPWSTR KeyName, DWORD Level, LPBYTE * pbufptr ) { NTSTATUS Status; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsLocalServiceInfoGetW\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) { Status = STATUS_INVALID_PARAMETER; } else if ( LlsCapabilityIsSupported( Handle, LLS_CAPABILITY_LOCAL_SERVICE_API ) ) { try { Status = LlsrLocalServiceInfoGetW( pLocalHandle->Handle, KeyName, Level, (PLLS_LOCAL_SERVICE_INFOW *) pbufptr ); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } } else if ( 0 != Level ) { Status = STATUS_INVALID_LEVEL; } else if ( NULL == KeyName ) { Status = STATUS_INVALID_PARAMETER; } else { PLLS_LOCAL_SERVICE_INFO_0W pLocalService = NULL; LONG lError; HKEY hKeyLocalMachine; lError = RegConnectRegistry( pLocalHandle->szServerName, HKEY_LOCAL_MACHINE, &hKeyLocalMachine ); if ( ERROR_SUCCESS == lError ) { HKEY hKeyLicenseInfo; lError = RegOpenKeyEx( hKeyLocalMachine, REG_KEY_LICENSE, 0, KEY_READ, &hKeyLicenseInfo ); if ( ERROR_SUCCESS == lError ) { HKEY hKeyService; lError = RegOpenKeyEx( hKeyLicenseInfo, KeyName, 0, KEY_READ, &hKeyService ); if ( ERROR_SUCCESS == lError ) { pLocalService = MIDL_user_allocate( sizeof( *pLocalService ) ); if ( NULL == pLocalService ) { lError = ERROR_OUTOFMEMORY; } else { DWORD cbData; cbData = sizeof( pLocalService->Mode ); lError = RegQueryValueEx( hKeyService, REG_VALUE_MODE, NULL, NULL, (LPBYTE) &pLocalService->Mode, &cbData ); if ( ERROR_SUCCESS == lError ) { cbData = sizeof( pLocalService->FlipAllow ); lError = RegQueryValueEx( hKeyService, REG_VALUE_FLIP, NULL, NULL, (LPBYTE) &pLocalService->FlipAllow, &cbData ); if ( ERROR_SUCCESS == lError ) { cbData = sizeof( pLocalService->ConcurrentLimit ); lError = RegQueryValueEx( hKeyService, REG_VALUE_LIMIT, NULL, NULL, (LPBYTE) &pLocalService->ConcurrentLimit, &cbData ); if ( ERROR_SUCCESS == lError ) { DWORD cbKeyName; DWORD cbDisplayName; DWORD cbFamilyDisplayName; cbData = sizeof( pLocalService->HighMark ); lError = RegQueryValueEx( hKeyService, REG_VALUE_HIGHMARK, NULL, NULL, (LPBYTE) &pLocalService->HighMark, &cbData ); if ( ERROR_SUCCESS != lError ) { pLocalService->HighMark = 0; lError = ERROR_SUCCESS; } if ( ( ERROR_SUCCESS == RegQueryValueEx( hKeyService, REG_VALUE_NAME, NULL, NULL, NULL, &cbDisplayName ) ) && ( ERROR_SUCCESS == RegQueryValueEx( hKeyService, REG_VALUE_FAMILY, NULL, NULL, NULL, &cbFamilyDisplayName ) ) ) { cbKeyName = sizeof( *KeyName ) * ( 1 + lstrlen( KeyName ) ); pLocalService->KeyName = MIDL_user_allocate( cbKeyName ); if ( NULL == pLocalService->KeyName ) { lError = ERROR_OUTOFMEMORY; } else { lstrcpy( pLocalService->KeyName, KeyName ); pLocalService->DisplayName = MIDL_user_allocate( cbDisplayName ); if ( NULL == pLocalService->DisplayName ) { lError = ERROR_OUTOFMEMORY; } else { lError = RegQueryValueEx( hKeyService, REG_VALUE_NAME, NULL, NULL, (LPBYTE) pLocalService->DisplayName, &cbDisplayName ); if ( ERROR_SUCCESS == lError ) { pLocalService->FamilyDisplayName = MIDL_user_allocate( cbFamilyDisplayName ); if ( NULL == pLocalService->FamilyDisplayName ) { lError = ERROR_OUTOFMEMORY; } else { lError = RegQueryValueEx( hKeyService, REG_VALUE_FAMILY, NULL, NULL, (LPBYTE) pLocalService->FamilyDisplayName, &cbFamilyDisplayName ); if ( ERROR_SUCCESS != lError ) { MIDL_user_free( pLocalService->FamilyDisplayName ); } } } if ( ERROR_SUCCESS != lError ) { MIDL_user_free( pLocalService->DisplayName ); } } if ( ERROR_SUCCESS != lError ) { MIDL_user_free( pLocalService->KeyName ); } } } } } } if ( ERROR_SUCCESS != lError ) { MIDL_user_free( pLocalService ); } } RegCloseKey( hKeyService ); } RegCloseKey( hKeyLicenseInfo ); } RegCloseKey( hKeyLocalMachine ); } switch ( lError ) { case ERROR_SUCCESS: Status = STATUS_SUCCESS; break; case ERROR_FILE_NOT_FOUND: case ERROR_PATH_NOT_FOUND: Status = STATUS_OBJECT_NAME_NOT_FOUND; break; case ERROR_ACCESS_DENIED: Status = STATUS_ACCESS_DENIED; break; default: Status = STATUS_UNSUCCESSFUL; break; } if ( STATUS_SUCCESS == Status ) { *pbufptr = (LPBYTE) pLocalService; } } return Status; } NTSTATUS NTAPI LlsLocalServiceInfoGetA( LLS_HANDLE Handle, DWORD Level, LPSTR KeyName, LPBYTE * pbufptr ) { NTSTATUS Status; PLOCAL_HANDLE pLocalHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsLocalServiceInfoGetA\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) { Status = STATUS_INVALID_PARAMETER; } else if ( LlsCapabilityIsSupported( Handle, LLS_CAPABILITY_LOCAL_SERVICE_API ) ) { try { Status = LlsrLocalServiceInfoGetA( pLocalHandle->Handle, KeyName, Level, (PLLS_LOCAL_SERVICE_INFOA *) pbufptr ); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } } else { Status = STATUS_NOT_SUPPORTED; } return Status; } NTSTATUS NTAPI LlsLicenseRequest2W( LLS_HANDLE Handle, LPWSTR Product, ULONG VersionIndex, BOOLEAN IsAdmin, ULONG DataType, ULONG DataSize, PBYTE Data, PHANDLE pLicenseHandle ) { NTSTATUS Status; PLOCAL_HANDLE pLocalHandle; LICENSE_HANDLE RpcLicenseHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsLicenseRequestW\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if ((pLocalHandle == NULL) || (pLicenseHandle == NULL)) { Status = STATUS_INVALID_PARAMETER; } else { try { RtlEnterCriticalSection( &g_RpcHandleLock ); lsapirpc_handle = pLocalHandle->llsrpc_handle; Status = LlsrLicenseRequestW( &RpcLicenseHandle, Product, VersionIndex, IsAdmin, DataType, DataSize, Data ); RtlLeaveCriticalSection( &g_RpcHandleLock ); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } *pLicenseHandle = RpcLicenseHandle; } return Status; } NTSTATUS NTAPI LlsLicenseRequestW( LLS_HANDLE Handle, LPWSTR Product, ULONG VersionIndex, BOOLEAN IsAdmin, ULONG DataType, ULONG DataSize, PBYTE Data, LPDWORD pLicenseHandle ) { HANDLE RealLicenseHandle = (HANDLE)(-1); NTSTATUS status; if (sizeof(ULONG) == sizeof(HANDLE)) { // Should still work on Win32 status = LlsLicenseRequest2W(Handle,Product,VersionIndex,IsAdmin,DataType,DataSize,Data,&RealLicenseHandle); if (NULL != pLicenseHandle) *pLicenseHandle = PtrToUlong(RealLicenseHandle); } else { status = STATUS_NOT_IMPLEMENTED; if (NULL != pLicenseHandle) *pLicenseHandle = (ULONG) 0xFFFFFFFF; } return status; } NTSTATUS NTAPI LlsLicenseRequest2A( LLS_HANDLE Handle, LPSTR Product, ULONG VersionIndex, BOOLEAN IsAdmin, ULONG DataType, ULONG DataSize, PBYTE Data, PHANDLE pLicenseHandle ) { return STATUS_NOT_SUPPORTED; } NTSTATUS NTAPI LlsLicenseRequestA( LLS_HANDLE Handle, LPSTR Product, ULONG VersionIndex, BOOLEAN IsAdmin, ULONG DataType, ULONG DataSize, PBYTE Data, LPDWORD pLicenseHandle ) { return STATUS_NOT_SUPPORTED; } NTSTATUS NTAPI LlsLicenseFree2( LLS_HANDLE Handle, HANDLE LicenseHandle ) { NTSTATUS Status; PLOCAL_HANDLE pLocalHandle; LICENSE_HANDLE RpcLicenseHandle = (LICENSE_HANDLE) LicenseHandle; #ifdef API_TRACE dprintf(TEXT("LLSRPC.DLL: LlsLicenseFree\n")); #endif pLocalHandle = (PLOCAL_HANDLE) Handle; if (pLocalHandle == NULL) { Status = STATUS_INVALID_PARAMETER; } else { try { RtlEnterCriticalSection( &g_RpcHandleLock ); lsapirpc_handle = pLocalHandle->llsrpc_handle; Status = LlsrLicenseFree( &RpcLicenseHandle ); RtlLeaveCriticalSection( &g_RpcHandleLock ); } except (TRUE) { Status = I_RpcMapWin32Status(RpcExceptionCode()); #if DBG dprintf(TEXT("ERROR LLSRPC.DLL: RPC Exception: 0x%lX\n"), Status); #endif } } return Status; } NTSTATUS NTAPI LlsLicenseFree( LLS_HANDLE Handle, DWORD LicenseHandle ) { if (sizeof(ULONG) == sizeof(HANDLE)) { // Should still work on Win32 return LlsLicenseFree2(Handle,ULongToPtr(LicenseHandle)); } else { return STATUS_NOT_IMPLEMENTED; } }