//+-------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 2000-2000 // // File: expperm.cpp // // Contents: // // History: // // Note: //--------------------------------------------------------------------------- #include "pch.cpp" #include #include #include "lscommon.h" #include "debug.h" #include "globals.h" #include "db.h" #include "keypack.h" #include "clilic.h" #include "server.h" #define EXPIRE_THREAD_INITIAL_SLEEP (1000*60) /* 1 minute */ //--------------------------------------------------------------------- unsigned int WINAPI ExpirePermanentThread(void* ptr) { HANDLE hEvent=(HANDLE) ptr; DWORD dwStatus=ERROR_SUCCESS; LICENSEDCLIENT search_license; memset(&search_license,0,sizeof(search_license)); // // Signal initializer thread we are ready // SetEvent(hEvent); DBGPrintf( DBG_INFORMATION, DBGLEVEL_FUNCTION_DETAILSIMPLE, DBG_ALL_LEVEL, _TEXT("ExpirePermanent : ready...\n") ); // // Give service chance to initialize // Sleep(EXPIRE_THREAD_INITIAL_SLEEP); // // Forever loop // while(1) { PTLSDbWorkSpace pDbWkSpace = NULL; LICENSEDCLIENT found_license; TLSLICENSEPACK search_keypack; TLSLICENSEPACK found_keypack; search_license.ftExpireDate = time(NULL); memset(&found_license,0,sizeof(found_license)); memset(&search_keypack,0,sizeof(search_keypack)); memset(&found_keypack,0,sizeof(found_keypack)); if (!(ALLOCATEDBHANDLE(pDbWkSpace, g_EnumDbTimeout))) { goto do_sleep; } TLSDBLockKeyPackTable(); TLSDBLockLicenseTable(); CLEANUPSTMT; dwStatus = TLSDBLicenseEnumBeginEx( USEHANDLE(pDbWkSpace), TRUE, LSLICENSE_SEARCH_EXPIREDATE, &search_license, JET_bitSeekLE ); if (ERROR_SUCCESS != dwStatus) { TLSDBUnlockLicenseTable(); TLSDBUnlockKeyPackTable(); FREEDBHANDLE(pDbWkSpace); goto do_sleep; } while (1) { dwStatus = TLSDBLicenseEnumNextEx( USEHANDLE(pDbWkSpace), TRUE, // bReverse TRUE, // bAnyRecord &found_license ); if(dwStatus != ERROR_SUCCESS) { goto next_time; } // // See if this is the right product type // search_keypack.dwKeyPackId = found_license.dwKeyPackId; dwStatus = TLSDBKeyPackFind( USEHANDLE(pDbWkSpace), TRUE, LSKEYPACK_EXSEARCH_DWINTERNAL, &search_keypack, &found_keypack ); if(dwStatus != ERROR_SUCCESS) { continue; } // // only check licenses that we reissue // if(found_keypack.ucAgreementType != LSKEYPACKTYPE_RETAIL && found_keypack.ucAgreementType != LSKEYPACKTYPE_SELECT && found_keypack.ucAgreementType != LSKEYPACKTYPE_FREE && found_keypack.ucAgreementType != LSKEYPACKTYPE_OPEN ) { continue; } UCHAR ucKeyPackStatus = found_keypack.ucKeyPackStatus & ~LSKEYPACKSTATUS_RESERVED; // // Don't check pending activation key pack // if(ucKeyPackStatus != LSKEYPACKSTATUS_ACTIVE) { continue; } // // Only check per-seat and concurrent // if ((_tcsnicmp(found_keypack.szProductId, TERMSERV_PRODUCTID_SKU, _tcslen(TERMSERV_PRODUCTID_SKU)) != 0) && (_tcsnicmp(found_keypack.szProductId, TERMSERV_PRODUCTID_CONCURRENT_SKU, _tcslen(TERMSERV_PRODUCTID_CONCURRENT_SKU)) != 0)) { continue; } BEGIN_TRANSACTION(pDbWorkSpace); // // Return currently enumerated license. // dwStatus = TLSDBDeleteEnumeratedLicense(USEHANDLE(pDbWkSpace)); if (dwStatus == ERROR_SUCCESS) { // // Adjust available license number. // dwStatus = TLSDBReturnLicenseToKeyPack( USEHANDLE(pDbWkSpace), found_license.dwKeyPackId, 1 ); } if (dwStatus == ERROR_SUCCESS) { COMMIT_TRANSACTION(pDbWkSpace); InterlockedIncrement(&g_lPermanentLicensesReturned); } else { ROLLBACK_TRANSACTION(pDbWkSpace); } } next_time: TLSDBLicenseEnumEnd(USEHANDLE(pDbWkSpace)); TLSDBUnlockLicenseTable(); TLSDBUnlockKeyPackTable(); FREEDBHANDLE(pDbWkSpace); do_sleep: if (WAIT_OBJECT_0 == WaitForSingleObject(GetServiceShutdownHandle(),g_dwReissueExpireThreadSleep)) { break; } DBGPrintf( DBG_INFORMATION, DBG_FACILITY_RPC, DBGLEVEL_FUNCTION_DETAILSIMPLE, _TEXT("ExpirePermanent : woke up\n") ); } // // Initializer function will close the event handle // return dwStatus; } //--------------------------------------------------------------------- DWORD InitExpirePermanentThread() /*++ ++*/ { HANDLE hThread = NULL; unsigned int dwThreadId; HANDLE hEvent = NULL; DWORD dwStatus = ERROR_SUCCESS; HANDLE waithandles[2]; // // Create a event for namedpipe thread to signal it is ready. // hEvent = CreateEvent( NULL, FALSE, FALSE, // non-signal NULL ); if(hEvent == NULL) { dwStatus = GetLastError(); goto cleanup; } hThread = (HANDLE)_beginthreadex( NULL, 0, ExpirePermanentThread, hEvent, 0, &dwThreadId ); if(hThread == NULL) { dwStatus = GetLastError(); goto cleanup; } waithandles[0] = hEvent; waithandles[1] = hThread; // // Wait 30 second for thread to complete initialization // dwStatus = WaitForMultipleObjects( sizeof(waithandles)/sizeof(waithandles[0]), waithandles, FALSE, 30*1000 ); if(dwStatus == WAIT_OBJECT_0) { // // thread is ready // dwStatus = ERROR_SUCCESS; } else { if(dwStatus == (WAIT_OBJECT_0 + 1)) { // // Thread terminate abnormally // GetExitCodeThread( hThread, &dwStatus ); } else { dwStatus = TLS_E_SERVICE_STARTUP_CREATE_THREAD; } } cleanup: if(hEvent != NULL) { CloseHandle(hEvent); } if(hThread != NULL) { CloseHandle(hThread); } return dwStatus; }