|
Yes. One solution is CFileDialog.
Kuphryn
|
|
|
|
|
I think you should take a look at the CFileDialog class in the MSDN for using the "open file" common dialog.
CFileDialog
The paths retreived from the CFileDialog s are all absolute path, so you need to change it to relative paths yourself.
I did not try to get folder paths using this common dialog but you may use the "Browse For Folder" dialog that can be used through the SHBrowseForFolder() shell function. Again you will find it in the MSDN.
SHBrowseForFolder()
This function could be a little complicated to use but I think there are some wrapper classes on code project for it.
For the last part cocerning the 8.3 paths there is the API function GetShortPathName( ) for doing this and here is its parameters.
DWORD GetShortPathName(
LPCTSTR lpszLongPath,
LPTSTR lpszShortPath,
DWORD cchBuffer
);
|
|
|
|
|
Thank you very much for your help.
1. I couldn't understand how the shell function SHBrowseForFolder() works. Could you please tell me either how to use it or how to avoid it?
2. Is there a way to find the path of the program? This way I could remove it from the path to get a relative one.
3. How can I use an API function inside my MFC application?
Thank you again.
<marquee>Hosam Aly Mahmoud
|
|
|
|
|
1. As i told you in my post you could find a wrapper class for the SHBrowseForFolder( ) on code project this is its link http://www.codeproject.com/shell/cxsbrowsefolder.asp
2. The best way to get the program path exactly is to use the function GetModuleFileName() this is its declaration:
DWORD GetModuleFileName(<br />
HMODULE hModule,
LPTSTR lpFilename,
DWORD nSize
);
This function gives you the whole path to your program including the file name. Just remove the file name and you get theabsolute path of the program.
This is an example of how to use it to get the program path:
TCHAR procPath[MAX_PATH];
GetModuleFileName(hInst, procPath, MAX_PATH * sizeof(TCHAR));
CString strPath = procPath;
strPath = strPath.Left(str.ReverseFind('\\'));
But in some cases this is not the working path of the program (i.e. the working path is the path assumed if you just gave the program a file name only). One of this case is if you tried to double click a document to be opened with your program , in this case the working path will be that of the document. Any way to get the working path you may use the funcion GetCurrentDirectory()
DWORD GetCurrentDirectory(<br />
DWORD nBufferLength,
LPTSTR lpBuffer
);
it returns the current working directory of the program. See which one suits your situation and use it.
3. MFC are wrappers for the API functoins, you can call API functions anywhere in your MFC project as any other function, but in some cases an MFC method could have the same name as an API in this case you should preceed the function call with a double scope.
e.g. the method SetWindowText() if you want to call the API SetWindowText() instead of it call it like that
::SetWindowText()
|
|
|
|
|
Thank you very much for your appreciated help.
Now I want to remove the path from the filename I got from the Browse button. I shall tell you of a way I tried to use (before I read your second reply).
I used system ( "cd >> dir" ) to get the program's path, read it in a buffer and then compared it to the first characters in the filename. To take out the path, here is the code I used:
for (short i = 0; i < length; i ++)
if ( FileName.GetAt(i) != path.GetAt(i) ) { i=-1; break; }
if (i == -1) break;
for (short j = 0; i <= FileName.GetLength(); i ++, j++)
FileName.SetAt (j, FileName.GetAt(i) );
This part of code was inside a loop, and length is the length of the path of the program. FileName is the buffer in which I stored the filename from the browse button. The problem with the above code is that it doesn't work when the program is at the root folder of a partition. What do you think is the reason?
I am thinking of using a similar code (with GetModuleFileName instead of system ( "cd >> dir" ) . But shouldn't this give me the same problem?
If you find that my method was faulty somehow, please tell me.
Again thank you for your help.
<marquee>Hosam Aly Mahmoud
|
|
|
|
|
Let's say I have a some user mode C code, and I want to execute some privilged instruction, like wrmsr.
I write a function in user mode called mywrmsr( ARGS args ); with a bunch of instructions that can't be executed in user mode.
Then I send the address of this function (and the args) to a kernel driver with an IOCTL.
The kernel driver executes the code given by the function *.
Will this work???
Jeff Yunes
Georgia Institute of Technology
Intel Corporation
|
|
|
|
|
I am trying to compile a file that includes stl.h
I get fatal error C1083: cannot not open include file 'stl.h': No such file ....
How do I use stl in Visual C++?
|
|
|
|
|
You need to include each one individually, for example, for vectors, you need to include
#include <vector>
There also might be a global include for all STL headers.
Maximilien Lincourt
For success one must aquire one's self
|
|
|
|
|
Also, if you don't put:
using namespace std;
You will have to explicitly specify the STL:
std::vector<int> MyInts;
- Nitron
"Those that say a task is impossible shouldn't interrupt the ones who are doing it." - Chinese Proverb
|
|
|
|
|
Is there a way to retrieve the access token (either primary or impersonated) of the user currently logged-on to the console? I need this so I can execute a process in that user's security context from an NT Service running in the System context.
Any suggestions?
|
|
|
|
|
|
Alrighty, that did point out a few functions i could use. Thanks However, my problem still remains. If i'm currently running as a service (in the SYSTEM context), how can i find out (a) if there is a user logged on to the console, and (b) who they are so i can spawn a process running under their context?
I've been searching high and low for information on this, and all i've found so far is that I must be running as that user in order to get information about them. There must be a way to find this information, though.
My specific application is this: If my service wants to spawn an instance of IE and the currently logged-on user has a proxy setting, the instance of IE that gets opened by my service has no knowledge of that proxy setting since its running unser the SYSTEM account, and not that specific user's account.
I had thought about trying to enumerate all the logged-in users and finding out if one of them is logged on locally...that would do it, i believe. But I haven't found a way to do that. There was also mention of creating a GINA to trap the username of who logged on, but i have a feeling this wouldn't work for my application.
|
|
|
|
|
Neflyte wrote:
If my service wants to spawn an instance of IE and the currently logged-on user has a proxy setting, the instance of IE that gets opened by my service has no knowledge of that proxy setting since its running unser the SYSTEM account, and not that specific user's account.
well, that bits 'easy' - look for tqcrunas from www.quimeras.com
so, we are back to the original problem - finding out the logged on user .. you could use a GINA, but thats a lot of work ... if it was W2k, there are system log on hooks - http://www.codeproject.com/system/winlogon_notification_package.asp [^] shows these...
I still cant help the feeling that Ive seen it done, by walking through the process list, getting the sids etc of proceses and then ??? .. hmmmmm.. sorry I cant be of more help right now - I'll see if I have anything at home for it, if you're still interested/havnt solved it by tonight, my time (GMT +11.00)
'G'
|
|
|
|
|
this is reply #2
maybe this will help - I did a quick search for 'enumerate logged on users' through google .. :-
You'll have to get access to the user's desktop. The easiest way to do this is to 'impersonate' the security context of the logged-on user using one of the user's process token. Some 'pseudocode' to illustrate it:
HANDLE GetTokenOfLoggedOnUser()
{
HANDLE hToken;
HANDLE hProcess;
DWORD dwPID;
// find PID of 'explorer.exe'
// HOWTO: Enumerate Applications in Win32
// http://support.microsoft.com/support/kb/articles/Q175/0/30.ASP
hProcess = OpenProcess ( PROCESS_ALL_ACCESS,
TRUE,
dwPID
);
if ( !OpenProcessToken ( hProcess,
TOKEN_QUERY | TOKEN_IMPERSONATE,
&hToken
)
) return ( INVALID_HANDLE_VALUE);
return ( hToken);
}
//Error checking & 'CloseHandle()' omitted for brevity
DWORD dwThreadId;
HWINSTA hwinstaSave;
HDESK hdeskSave;
HWINSTA hwinstaUser;
HDESK hdeskUser;
int result;
/*
* Ensure connection to service window station and desktop, and
* save their handles.
*/
GetDesktopWindow();
hwinstaSave = GetProcessWindowStation();
dwThreadId = GetCurrentThreadId();
hdeskSave = GetThreadDesktop(dwThreadId);
/*
* Impersonate the client and connect to the User's
* window station and desktop.
*/
InpersonateLoggedOnUser ( GetTokenOfLoggedOnUser();
hwinstaUser = OpenWindowStation(lpszWindowStation, FALSE, MAXIMUM_ALLOWED);
if (hwinstaUser == NULL) {
RevertToSelf();
return 0;
}
SetProcessWindowStation(hwinstaUser);
hdeskUser = OpenDesktop(lpszDesktop, 0, FALSE, MAXIMUM_ALLOWED);
RevertToSelf();
if (hdeskUser == NULL) {
SetProcessWindowStation(hwinstaSave);
CloseWindowStation(hwinstaUser);
return 0;
}
SetThreadDesktop(hdeskUser);
/*
* Display message box (for example's sakes) or enumerate the windows
*/
dwGuiThreadId = dwThreadId;
result = MessageBox(NULL, lpszText, lpszTitle, fuStyle);
dwGuiThreadId = 0;
/*
* Restore window station and desktop.
*/
SetThreadDesktop(hdeskSave);
SetProcessWindowStation(hwinstaSave);
CloseDesktop(hdeskUser);
CloseWindowStation(hwinstaUser);
RevertToSelf();
}
To elaborate: You can't 'simply' acces the user's desktop, as it is a secured object. But 'ImpersonateLoggedOnUser()' provides a way to get the same credentials as the user that 'owns' the desktop, so you'll be able to access it. All you need is the access token of a process running in the context of the logged-on user, so 'OpenProcessToken()' will do the job for you...
|
|
|
|
|
reply #3 ...Im feeling that some of the above info IS on the right track .. to see why, go to www.sysinternals.com, download 'Process Explorer' and run it .. it has a column called 'Owner' .. Explorer comes up for example as MBF336\busgjl (machine name\logon id) .. so the info - SID etc is there for processes, its just a matter of decoding it ...
'G'
|
|
|
|
|
Wow...thanks for all this beautiful info! I was thinking along those lines earlier today, but my brain started hurting and i had to quit
It completely escaped me that i could get the token of the running explorer.exe. Thats almost certainly always running as the current user (except in the small chance that the user has replaced their shell).
I can't thank you enough for this awesome bit of help!
...alan
|
|
|
|
|
Neflyte wrote:
I can't thank you enough for this awesome bit of help!
no problem - and just to proove that the world sometimes is a nice place, here's some more - even if you dont use it now, its good stuff to remember for a rainy day (ps.. its 0:34am down here in Sydney, Australia, so If I make any spello's, you'll have to forgive me)
ok, references :-
1) 'Windows NT Security' by Nik Okuntseff has all sorts of gems - avail thru RDBOOKS, code downloadable
2) ** THE BEST ** 'Programming Windows Security', Keith Brown (I had Amazon fly me down a copy).. now, if you surf on over to www.develop.com/kbrown/security/samples.htm[^] check out the samples 'Session Viewer' and 'Token Dump Component' - these'll provide you with all the ammo I suspect you need, and yet another way of doing it, using the active desktop and Winsta0
sleep, must have sleep .. toodle pip from this side of the world ...
'G'
|
|
|
|
|
Okay, i've implemented most of what you wrote here. Now I'm at a different problem.
I'm able to get the access token of the currently logged on user, but when I call ImpersonateLoggedOnUser, i always get an 'Access is Denied' error from GetLastError().
I thought I might be able to circumvent using that function call by just calling CreateProcessAsUser, but something tells me that I need to ImpersonateLoggedOnUser() before i can make the CreateProcessAsUser call.
Any thoughts on that?
...alan
|
|
|
|
|
ouch .. this is now getting into a very hard area .. the best way of doing this, is to go back to afore-mentioned web page for Keith Brown, grab his cmdasuser example, read that, and all might become clear.. if it doesnt, and you're desperate to solve this problem, either for your boss or for a client, read on now .....
did I give you the url for www.quimeras.com[^] ??? - they sell a few components that make impersonation a breeze ie 'runas' type functionality ... there's also a 'Security Context Component' from www.codemill.net (www.codemill.net/products/secctx/doc.htm[^]) which I gather is meant for more 'webby' asp/iis ??? type stuff ...
you might ask, having fed you all the info I had, why then point you toward two commercial implementations ?? well, it would have taken significantly longer in one case to write/adapt other's code to my problem, so while knowing the theory behind what I was doing was very valuable (specially since I had to justify myself to our Security Manager in great detail), it was more expedient to simply purchase a product, get the job done, and move onto the next fight(Im not affiliated with quimeras or codemill - I just beleive they had the best quick way of solving the problem)
hope this helps ...
ps.. I beleive from memory, the answer lies in that the process doing the impersonation has to be 'priviliged', ie, running in a system context ...
good luck
'G'
|
|
|
|
|
Why is it that in
CModeLess::CModeLess(CWnd* pParent )
: CDialog(CModeLess::IDD, pParent)
{
m_parent=pParent;
}
I can send a message or post and it gets to the right view. But if I try to set a parent member (parent is CTView), it says thats not a member of CWnd....fine So I try to cast the m_pParent to a CTVIew* pointer, but it doesnt like it if I do a #include "tView.h" in the CDialog derived class, since "myCDlg.h" is included in TView.h....something circular going on...
SO I tried forward declaring the CTVIew class in my CDlg .h file but it didnt like that either....
SO why does my message get to the right parent, but I cant set a member of the parent? If I could cast it I could but it doesnt look like its legal...?
Appreciate your help,
ns
|
|
|
|
|
You'll have to #include tView.h in the cpp file, and summon the pointer when you need it rather than have it as a member of the class. I've had to do this before when working with incestuous modless dialogs in order to avoid circular inclusion.
- Nitron
"Those that say a task is impossible shouldn't interrupt the ones who are doing it." - Chinese Proverb
|
|
|
|
|
So you're saying I shouldnt save the parent pointer that comes into Create(). Guess I should be looking at getparent.....?
Appreciate your help,
ns
|
|
|
|
|
right.
CParentClass* pParent = static_cast<CParentClass*>(GetParent());
- Nitron
"Those that say a task is impossible shouldn't interrupt the ones who are doing it." - Chinese Proverb
|
|
|
|
|
Hello to everyone
I have an *.exe file which i made in c++, and wrote it on a cd. But i have not save the files of the project. Now i want to change some things in the program and i cannot open the source code ( *.cpp) because i dont have it, only the *.exe file. Is there a way to retrive it or i have to make it again from the begging?
Please late me know if someone knows a way to do so.
Thanks for your time
Tace care all of youselves
|
|
|
|
|
It's gone.
Next time save your source. It's more valuable than the .exe
|
|
|
|
|