BOOL uac::RunAsStdUser(LPCTSTR lpszExePath, LPCTSTR lpszParameters) { if (!IsAdminElevated()) RunShellExecute(FALSE, lpszExePath, lpszParameters); HRESULT hr = 0; // Choose a name for the task. LPCTSTR pszTaskName = L"RunAsStdUser Task"; // Create an instance of the Task Service. ComObjHelper<ITaskService> iService; hr = CoCreateInstance(CLSID_TaskScheduler, NULL, CLSCTX_INPROC_SERVER, IID_ITaskService, (void**)&(iService.m_pComObj)); FAILED_IF(hr); // Connect to the task service. hr = iService.m_pComObj->Connect(_variant_t(), _variant_t(), _variant_t(), _variant_t()); FAILED_IF(hr); // Get the pointer to the root task folder. This folder will hold the // new task that is registered. ComObjHelper<ITaskFolder> iRootFolder; hr = iService.m_pComObj->GetFolder(_bstr_t(L"\\"), &iRootFolder.m_pComObj); FAILED_IF(hr); // If the same task exists, remove it. iRootFolder.m_pComObj->DeleteTask(_bstr_t(pszTaskName), 0); // ignore error message, if any // Create the task builder object to create the task. ComObjHelper<ITaskDefinition> iTask; hr = iService.m_pComObj->NewTask(0, &iTask.m_pComObj); FAILED_IF(hr); // Get the registration info for setting the identification. ComObjHelper<IRegistrationInfo> iRegInfo; hr = iTask.m_pComObj->get_RegistrationInfo(&iRegInfo.m_pComObj); FAILED_IF(hr); hr = iRegInfo.m_pComObj->put_Author(L"RunAsStdUser"); FAILED_IF(hr); // Create the principal for the task ComObjHelper<IPrincipal> iPrincipal; hr = iTask.m_pComObj->get_Principal(&iPrincipal.m_pComObj); FAILED_IF(hr); // Set up principal information: hr = iPrincipal.m_pComObj->put_Id(_bstr_t(L"RunAsStdUser_Principal")); FAILED_IF(hr); hr = iPrincipal.m_pComObj->put_LogonType(TASK_LOGON_INTERACTIVE_TOKEN); FAILED_IF(hr); // Run the task with the least privileges (LUA) hr = iPrincipal.m_pComObj->put_RunLevel(TASK_RUNLEVEL_LUA); FAILED_IF(hr); // Create the settings for the task ComObjHelper<ITaskSettings> iSettings; hr = iTask.m_pComObj->get_Settings(&iSettings.m_pComObj); FAILED_IF(hr); // Set setting values for the task. hr = iSettings.m_pComObj->put_StartWhenAvailable(VARIANT_BOOL(true)); FAILED_IF(hr); // Get the trigger collection to insert the registration trigger. ComObjHelper<ITriggerCollection> iTriggerCollection; hr = iTask.m_pComObj->get_Triggers(&iTriggerCollection.m_pComObj); FAILED_IF(hr); // Add the registration trigger to the task. ComObjHelper<ITrigger> iTrigger; hr = iTriggerCollection.m_pComObj->Create(TASK_TRIGGER_REGISTRATION, &iTrigger.m_pComObj); FAILED_IF(hr); ComObjHelper<IRegistrationTrigger> iRegistrationTrigger; hr = iTrigger.m_pComObj->QueryInterface( IID_IRegistrationTrigger, (void**)&iRegistrationTrigger.m_pComObj); FAILED_IF(hr); hr = iRegistrationTrigger.m_pComObj->put_Id(_bstr_t(L"RunAsStdUser_Trigger")); FAILED_IF(hr); // Define the delay for the registration trigger. hr = iRegistrationTrigger.m_pComObj->put_Delay(L"PT0S"); // 0 second delay of execution; FAILED_IF(hr); // Add an Action to the task. This task will execute notepad.exe. // Get the task action collection pointer. ComObjHelper<IActionCollection> iActionCollection; hr = iTask.m_pComObj->get_Actions(&iActionCollection.m_pComObj); FAILED_IF(hr); // Create the action, specifying that it is an executable action. ComObjHelper<IAction> iAction; hr = iActionCollection.m_pComObj->Create(TASK_ACTION_EXEC, &iAction.m_pComObj); FAILED_IF(hr); // QI for the executable task pointer. ComObjHelper<IExecAction> iExecAction; hr = iAction.m_pComObj->QueryInterface( IID_IExecAction, (void**)&iExecAction.m_pComObj); FAILED_IF(hr); // Set the path of the executable to notepad.exe. hr = iExecAction.m_pComObj->put_Path(_bstr_t(lpszExePath)); if (lpszParameters) { hr = iExecAction.m_pComObj->put_Arguments(_bstr_t(lpszParameters)); FAILED_IF(hr); } // TODO: //if (pszDirectory) //{ // hr = iExecAction.m_pComObj->put_WorkingDirectory(_bstr_t(pszDirectory)); //} // Save the task in the root folder. ComObjHelper<IRegisteredTask> iRegisteredTask; hr = iRootFolder.m_pComObj->RegisterTaskDefinition( _bstr_t(pszTaskName), iTask.m_pComObj, TASK_CREATE_OR_UPDATE, _variant_t(), _variant_t(), TASK_LOGON_INTERACTIVE_TOKEN, _variant_t(L""), &iRegisteredTask.m_pComObj); FAILED_IF(hr); return TRUE; }
int main(int argc, char *argv[]) { unsigned char *core; int i; size_t s, s2; pid_t pid; int size; MM *mm; int n; char *cp[1025]; int version; struct count_test { int count; int prev; } *ct; setbuf(stderr, NULL); /* ** ** Test Global Library API ** */ fprintf(stderr, "\n*** TESTING GLOBAL LIBRARY API ***\n\n"); fprintf(stderr, "Fetching library version\n"); version = mm_lib_version(); FAILED_IF(version == 0x0); fprintf(stderr, "version = 0x%X\n", version); /* ** ** Test Low-Level Shared Memory API ** */ fprintf(stderr, "\n*** TESTING LOW-LEVEL SHARED MEMORY API ***\n"); fprintf(stderr, "\n=== Testing Memory Segment Access ===\n"); fprintf(stderr, "Creating 16KB shared memory core area\n"); core = mm_core_create(1024*16, NULL); FAILED_IF(core == NULL); s = mm_core_size(core); FAILED_IF(s == 0); fprintf(stderr, "actually allocated core size = %d\n", s); fprintf(stderr, "Writing 0xF5 bytes to shared memory core area\n"); for (i = 0; i < s; i++) { fprintf(stderr, "write to core[%06d]\r", i); core[i] = 0xF5; } fprintf(stderr, "\n"); fprintf(stderr, "Reading back 0xF5 bytes from shared memory core area\n"); for (i = 0; i < s; i++) { fprintf(stderr, "read from core[%06d]\r", i); if (core[i] != 0xF5) { fprintf(stderr, "Offset %d: 0xF5 not found (found 0x%X\n", i, core[i]); exit(0); } } fprintf(stderr, "\n"); fprintf(stderr, "Destroying shared memory core area\n"); mm_core_delete(core); fprintf(stderr, "\n=== Testing Memory Locking ===\n"); fprintf(stderr, "Creating small shared memory core area\n"); ct = mm_core_create(sizeof(struct count_test), NULL); FAILED_IF(ct == NULL); s = mm_core_size(ct); FAILED_IF(s == 0); fprintf(stderr, "actually allocated core size = %d\n", s); ct->prev = 0; ct->count = 1; if ((pid = fork()) == 0) { /* child */ while (ct->count < 32768) { if (!mm_core_lock(ct, MM_LOCK_RW)) { fprintf(stderr, "locking failed (child)\n"); FAILED_IF(1); } if (ct->prev != (ct->count-1)) { fprintf(stderr, "Failed, prev=%d != count=%d\n", ct->prev, ct->count); exit(1); } ct->count += 1; fprintf(stderr, "count=%06d (child )\r", ct->count); ct->prev += 1; if (!mm_core_unlock(ct)) { fprintf(stderr, "locking failed (child)\n"); FAILED_IF(1); } } exit(0); } /* parent ... */ while (ct->count < 32768) { if (!mm_core_lock(ct, MM_LOCK_RW)) { fprintf(stderr, "locking failed (parent)\n"); FAILED_IF(1); } if (ct->prev != (ct->count-1)) { fprintf(stderr, "Failed, prev=%d != count=%d\n", ct->prev, ct->count); exit(1); } ct->count += 1; fprintf(stderr, "count=%06d (parent)\r", ct->count); ct->prev += 1; if (!mm_core_unlock(ct)) { fprintf(stderr, "locking failed (parent)\n"); kill(pid, SIGTERM); FAILED_IF(1); } } waitpid(pid, NULL, 0); fprintf(stderr, "\n"); fprintf(stderr, "Destroying shared memory core area\n"); mm_core_delete(ct); /* ** ** Test Standard Malloc-style API ** */ fprintf(stderr, "\n*** TESTING STANDARD MALLOC-STYLE API ***\n"); fprintf(stderr, "\n=== Testing Allocation ===\n"); fprintf(stderr, "Creating MM object\n"); size = mm_maxsize(); if (size > 1024*1024*1) size = 1024*1024*1; mm = mm_create(size, NULL); FAILED_IF(mm == NULL) mm_display_info(mm); s = mm_available(mm); FAILED_IF(s == 0); fprintf(stderr, "actually available bytes = %d\n", s); fprintf(stderr, "Allocating areas inside MM\n"); n = 0; for (i = 0; i < 1024; i++) cp[i] = NULL; for (i = 0; i < 1024; i++) { fprintf(stderr, "total=%09d allocated=%09d add=%06d\r", s, n, (i+1)*(i+1)); s2 = mm_available(mm); if ((i+1)*(i+1) > s2) { cp[i] = mm_malloc(mm, (i+1)*(i+1)); if (cp[i] != NULL) { fprintf(stderr, "\nExpected an out of memory situation. Hmmmmm\n"); FAILED_IF(1); } break; } cp[i] = mm_malloc(mm, (i+1)*(i+1)); n += (i+1)*(i+1); FAILED_IF(cp[i] == NULL) memset(cp[i], 0xF5, (i+1)*(i+1)); } mm_display_info(mm); fprintf(stderr, "\n=== Testing Defragmentation ===\n"); fprintf(stderr, "Fragmenting memory area by freeing some selected areas\n"); for (i = 0; i < 1024; i++) { if (i % 2 == 0) continue; if (cp[i] != NULL) mm_free(mm, cp[i]); cp[i] = NULL; } mm_display_info(mm); fprintf(stderr, "Freeing all areas\n"); for (i = 0; i < 1024; i++) { mm_free(mm, cp[i]); } mm_display_info(mm); fprintf(stderr, "Checking for memory leaks\n"); s2 = mm_available(mm); if (s != s2) { fprintf(stderr, "Something is leaking, we've lost %d bytes\n", s - s2); FAILED_IF(1); } else { fprintf(stderr, "Fine, we have again %d bytes available\n", s2); } fprintf(stderr, "Destroying MM object\n"); mm_destroy(mm); /******/ fprintf(stderr, "\nOK - ALL TESTS SUCCESSFULLY PASSED.\n\n"); exit(0); }