GetOpenFileName in a service
-
I am attempting to use GetOpenFileName from a service on W2K and WXP. The service is set to interact with the desktop. The problem is that when the open dialog appears and the user selects the "Desktop" icon on the left panel of the open file dialog, it complains about "C:\Documents and Settings\LocalSystem\desktop" not existing. Note the "LocalDesktop" in that string. I want it to be the name of the current user. So, how do I tell GetOpenFileName to use the currently logged-on user's context when using the open file dialog? Do I need to impersonate the logged-on user before calling GetOpenFileName? If so, how do I do impersonation WITHOUT asking for user credentials? Some rudimentary example will suffice, you don't have to right the whole she-bang. Thank you in advance. ahz
-
I am attempting to use GetOpenFileName from a service on W2K and WXP. The service is set to interact with the desktop. The problem is that when the open dialog appears and the user selects the "Desktop" icon on the left panel of the open file dialog, it complains about "C:\Documents and Settings\LocalSystem\desktop" not existing. Note the "LocalDesktop" in that string. I want it to be the name of the current user. So, how do I tell GetOpenFileName to use the currently logged-on user's context when using the open file dialog? Do I need to impersonate the logged-on user before calling GetOpenFileName? If so, how do I do impersonation WITHOUT asking for user credentials? Some rudimentary example will suffice, you don't have to right the whole she-bang. Thank you in advance. ahz
After some research, I answered my own question: OPENFILENAME op; ZeroMemory(&op, sizeof(op)); op.lStructSize = sizeof(op); op.hwndOwner = m_hWnd; op.lpstrFilter = L"JavaScript Files (*.js)\0*.js\0VBScript Files (*.vbs)\0*.vbs\0All Files (*.*)\0*.*\0\0\0"; op.lpstrFile = m_wsFilePathBuf; op.nMaxFile = cPathSize; op.lpstrFileTitle = m_wsFileNameBuf; op.nMaxFileTitle = cNameSize; op.lpstrTitle = title.Length() ? title : L"Product Name Title"; op.Flags = OFN_DONTADDTORECENT | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_ENABLESIZING | OFN_EXPLORER | OFN_HIDEREADONLY; bool impersonated = false; DWORD processID; if (ProcessIsRunning(L"someuserprocess.exe", processID)) { HANDLE processHandle; HANDLE token = 0, duptoken = 0; BOOL result; DWORD size = 0; processHandle = ::OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_DUP_HANDLE, FALSE,processID); result = ::OpenProcessToken(processHandle, TOKEN_QUERY | TOKEN_IMPERSONATE | TOKEN_DUPLICATE, &token); result = result ? ::DuplicateToken(token, SecurityImpersonation, &duptoken) : FALSE; impersonated = (result ? ::ImpersonateLoggedOnUser(duptoken) : FALSE) == TRUE; } BOOL result = GetOpenFileName(&op); if (impersonated) { RevertToSelf(); impersonated = false; }
-
After some research, I answered my own question: OPENFILENAME op; ZeroMemory(&op, sizeof(op)); op.lStructSize = sizeof(op); op.hwndOwner = m_hWnd; op.lpstrFilter = L"JavaScript Files (*.js)\0*.js\0VBScript Files (*.vbs)\0*.vbs\0All Files (*.*)\0*.*\0\0\0"; op.lpstrFile = m_wsFilePathBuf; op.nMaxFile = cPathSize; op.lpstrFileTitle = m_wsFileNameBuf; op.nMaxFileTitle = cNameSize; op.lpstrTitle = title.Length() ? title : L"Product Name Title"; op.Flags = OFN_DONTADDTORECENT | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_ENABLESIZING | OFN_EXPLORER | OFN_HIDEREADONLY; bool impersonated = false; DWORD processID; if (ProcessIsRunning(L"someuserprocess.exe", processID)) { HANDLE processHandle; HANDLE token = 0, duptoken = 0; BOOL result; DWORD size = 0; processHandle = ::OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_DUP_HANDLE, FALSE,processID); result = ::OpenProcessToken(processHandle, TOKEN_QUERY | TOKEN_IMPERSONATE | TOKEN_DUPLICATE, &token); result = result ? ::DuplicateToken(token, SecurityImpersonation, &duptoken) : FALSE; impersonated = (result ? ::ImpersonateLoggedOnUser(duptoken) : FALSE) == TRUE; } BOOL result = GetOpenFileName(&op); if (impersonated) { RevertToSelf(); impersonated = false; }
-
After some research, I answered my own question: OPENFILENAME op; ZeroMemory(&op, sizeof(op)); op.lStructSize = sizeof(op); op.hwndOwner = m_hWnd; op.lpstrFilter = L"JavaScript Files (*.js)\0*.js\0VBScript Files (*.vbs)\0*.vbs\0All Files (*.*)\0*.*\0\0\0"; op.lpstrFile = m_wsFilePathBuf; op.nMaxFile = cPathSize; op.lpstrFileTitle = m_wsFileNameBuf; op.nMaxFileTitle = cNameSize; op.lpstrTitle = title.Length() ? title : L"Product Name Title"; op.Flags = OFN_DONTADDTORECENT | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_ENABLESIZING | OFN_EXPLORER | OFN_HIDEREADONLY; bool impersonated = false; DWORD processID; if (ProcessIsRunning(L"someuserprocess.exe", processID)) { HANDLE processHandle; HANDLE token = 0, duptoken = 0; BOOL result; DWORD size = 0; processHandle = ::OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_DUP_HANDLE, FALSE,processID); result = ::OpenProcessToken(processHandle, TOKEN_QUERY | TOKEN_IMPERSONATE | TOKEN_DUPLICATE, &token); result = result ? ::DuplicateToken(token, SecurityImpersonation, &duptoken) : FALSE; impersonated = (result ? ::ImpersonateLoggedOnUser(duptoken) : FALSE) == TRUE; } BOOL result = GetOpenFileName(&op); if (impersonated) { RevertToSelf(); impersonated = false; }
Good solution, just remember to close your handles when you're done. Also, a couple of points...
- What if there is no user running the process you're checking for?
- What if more than one user is running the process you're checking for? Do you use the right one?
Ryan
"Punctuality is only a virtue for those who aren't smart enough to think of good excuses for being late" John Nichol "Point Of Impact"
-
Good solution, just remember to close your handles when you're done. Also, a couple of points...
- What if there is no user running the process you're checking for?
- What if more than one user is running the process you're checking for? Do you use the right one?
Ryan
"Punctuality is only a virtue for those who aren't smart enough to think of good excuses for being late" John Nichol "Point Of Impact"
Ryan Binns wrote: Good solution, just remember to close your handles when you're done. yes, caught that and did it. Also, a couple of points... What if there is no user running the process you're checking for? First, in the product I'm developing is an endpoint security product, so if the process queried is not running, the product considers that a fatal error and causes user's machine to reboot. What if more than one user is running the process you're checking for? Do you use the right one? Second the product I'm developing is not supported on FUS or TSERVER or CITRIX metaframe. wouldn't make sense in those environments. Thanks for the comments.