Thread: subst command not working through createProcess()

  1. #1
    Registered User
    Join Date
    Dec 2008
    Posts
    3

    subst command not working through createProcess()

    Helo all,

    I try to do subst command to map a folder to a drive letter.

    I achieved it through command line.

    I did same thing via createProcess().

    It returns non zero value but the folder not get mapped to that drive letter.

    I am using windows2003 and NT.

    The part of the code:

    Code:
     STARTUPINFO si;
            PROCESS_INFORMATION pi;
            int flag, err, i;
    
            GetStartupInfo(&si);
    /*
            flag = 0;
            flag = CREATE_NEW_CONSOLE;
            flag = DETACHED_PROCESS;
            flag = CREATE_NEW_PROCESS_GROUP;
    */
            flag = 0;
    DebugLogMessage1(cmd);
            if(!CreateProcess(NULL, cmd, NULL, NULL, FALSE, flag,
                    NULL, NULL, &si, &pi)) {
                    err = GetLastError();
                    LogMsg(3, "RunCommand: Could not create process %s error=%d", cmd, err);
                    return;
            }
    The DebugLogMessage1(cmd); prints the value of cmd as subst R: C:\PROGRA~1\Syntegra

    Please give me the things went wrong in the above program or in the windows settings.


    Regards,
    Naga

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    I don't see anything DIRECTLY wrong, but what error message are you getting?

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    I would set the members of si explicitly (zero'ing it out first) instead of trying to pass in the parent processes si.

    gg

  4. #4
    Registered User
    Join Date
    Mar 2005
    Location
    Mountaintop, Pa
    Posts
    1,058
    Quote Originally Posted by 1inmillion View Post
    Helo all,

    I try to do subst command to map a folder to a drive letter.

    I achieved it through command line.

    I did same thing via createProcess().

    It returns non zero value but the folder not get mapped to that drive letter.

    I am using windows2003 and NT.

    The part of the code:

    Code:
     STARTUPINFO si;
            PROCESS_INFORMATION pi;
            int flag, err, i;
    
            GetStartupInfo(&si);
    /*
            flag = 0;
            flag = CREATE_NEW_CONSOLE;
            flag = DETACHED_PROCESS;
            flag = CREATE_NEW_PROCESS_GROUP;
    */
            flag = 0;
    DebugLogMessage1(cmd);
            if(!CreateProcess(NULL, cmd, NULL, NULL, FALSE, flag,
                    NULL, NULL, &si, &pi)) {
                    err = GetLastError();
                    LogMsg(3, "RunCommand: Could not create process %s error=%d", cmd, err);
                    return;
            }
    The DebugLogMessage1(cmd); prints the value of cmd as subst R: C:\PROGRA~1\Syntegra

    Please give me the things went wrong in the above program or in the windows settings.


    Regards,
    Naga
    Is there any specific reason for using the above method to map a drive as opposed to using something like WNetAddConnection2 ? This is assuming you're trying to map a folder on a remote workstation. But yet the DebugLogMessage implies that you're somehow trying to map a drive to a folder on the local workstation. I'm not sure I understand what exactly you're trying to accomplish. Can you provide some additional detail?

  5. #5
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    No, subst makes a directory translation so that an application thinks that R: is C:\program files\Syntegra (or whatever you put after the first drive: combination). It used to be that you'd swap floppy drives around to make naff applications run on B: or C: when it hard-coded A: as the "home-drive".

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  6. #6
    Registered User
    Join Date
    Mar 2005
    Location
    Mountaintop, Pa
    Posts
    1,058
    Quote Originally Posted by matsp View Post
    No, subst makes a directory translation so that an application thinks that R: is C:\program files\Syntegra (or whatever you put after the first drive: combination). It used to be that you'd swap floppy drives around to make naff applications run on B: or C: when it hard-coded A: as the "home-drive".

    --
    Mats
    I thought that subst looked vaguely familiar. It takes me back to my DOS 3.3 days. But anyway, please disregard my previous post relating to WNetAddConnection. It's not relevent.

  7. #7
    'Allo, 'Allo, Allo
    Join Date
    Apr 2008
    Posts
    639
    subst ain't working
    You may have more luck, or receive more pertinent error statuses, by going straight to the horses mouth which in this case is DefineDosDevice(0, "R:", "C:\\PROGRA~1\\Syntegra");

  8. #8
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    I could be way off here (and most likely am) but: The effects of subst go away after the process ends, right? It's not permanent. So just because the shell that gets created knows what R: means, doesn't mean anybody else does.

  9. #9
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by tabstop View Post
    I could be way off here (and most likely am) but: The effects of subst go away after the process ends, right? It's not permanent. So just because the shell that gets created knows what R: means, doesn't mean anybody else does.
    Not true - I use subst at work to get reasonable paths for different projects that I've got concurrently on my machine - and I just tried it on my Win2K system too.

    We use this because code is already several levels deep, e.g. x:/group/module/component/source/partsource/xx.cpp - if you then have to do something like "y:/mywork/projectx/current/" on top of that, it gets pretty hard to read the path - even with the subst drive I have some compnents that have so deep directory structure that an 80 character command-line is filled out so that I can't even do "cd" without going over the edge to the next line - not a bit problem, but gets a bit messy at times. Adding another two, three or four directory levels wouldn't help much!

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  10. #10
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by matsp View Post
    Not true - I use subst at work to get reasonable paths for different projects that I've got concurrently on my machine - and I just tried it on my Win2K system too.

    We use this because code is already several levels deep, e.g. x:/group/module/component/source/partsource/xx.cpp - if you then have to do something like "y:/mywork/projectx/current/" on top of that, it gets pretty hard to read the path - even with the subst drive I have some compnents that have so deep directory structure that an 80 character command-line is filled out so that I can't even do "cd" without going over the edge to the next line - not a bit problem, but gets a bit messy at times. Adding another two, three or four directory levels wouldn't help much!

    --
    Mats
    No, you're right. I'm not sure what I was thinking (probably confusing system startup with shell startup). Just call me "Emily Littella".

  11. #11
    Registered User
    Join Date
    Mar 2005
    Location
    Mountaintop, Pa
    Posts
    1,058
    Try your app with the following changes:
    Code:
    STARTUPINFO si = { 0 };
            PROCESS_INFORMATION pi = { 0 };
            int flag, err, i;
    
            GetStartupInfo(&si);
    /*
            flag = 0;
            flag = CREATE_NEW_CONSOLE;
            flag = DETACHED_PROCESS;
            flag = CREATE_NEW_PROCESS_GROUP;
    */
            flag = 0;
    DebugLogMessage1(cmd);
            if(!CreateProcess(NULL, cmd, NULL, NULL, FALSE, flag,
                    NULL, NULL, &si, &pi)) {
                    err = GetLastError();
                    LogMsg(3, "RunCommand: Could not create process %s error=%d", cmd, err);
                    return;
            }

    If the above changes do not solve your problem then you might try setting up the Comspec environment for the first parm to CreateProcess. And if that doesn't work, then you might try waiting until the child process finishes before exiting the function.

  12. #12
    Registered User
    Join Date
    Dec 2008
    Posts
    3
    Hi,

    Thanks for all who actively discussed on this thread.

    I have changed part of the code
    Code:
    if(!CreateProcess(NULL, cmd, NULL, NULL, FALSE, flag,
                    NULL, NULL, &si, &pi)) {
                    err = GetLastError();
                    LogMsg(3, "RunCommand: Could not create process %s error=%d", cmd, err);
                    return;
    }
    To

    Code:
    CreateProcess(NULL, cmd, NULL, NULL, FALSE, flag,NULL, NULL, &si, &pi);
                    err = GetLastError();
                    LogMsg(3, "RunCommand: Could not create process %s error=%d", cmd, err);
    Then I got the message “RunCommand: Could not create process subst R: "C:\Program Files\Syntegra" error=183”

    I used
    Code:
    ShellExecute(NULL, NULL, "subst.exe", "R: C:\PROGRA~1\Syntegra", NULL, SW_HIDE );
    And also used
    Code:
    DefineDosDevice(0, “R:”, “C:\\PROGRA~1\\Syntegra”);
    For all I am getting the same error 183(ERROR_ALREADY_EXISTS).

    But I am not seeing any R: drive in my “MyComputer” or start->run>r: also states no drive found.

    I also tried using the below code.

    Code:
            STARTUPINFO si = { 0 };
            PROCESS_INFORMATION pi = { 0 };

    Now my only question is how I am getting err 183, even though I am not able to see the drive R: in “MyComputer”. Interestingly I can use “subst” directly in command prompt and I am successful in viewing the dive R: in “MyComputer”.


    Regards,
    Naga

  13. #13
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Quote Originally Posted by Codeplug View Post
    I would set the members of si explicitly (zero'ing it out first) instead of trying to pass in the parent processes si.

    gg
    Meaning, don't call GetStartupInfo().
    Code:
    bool run(const char *cmd, PROCESS_INFORMATION *pi/*=0*/, bool bHide/*=true*/)
    {
        // CreateProcess() needs a non-const string
        char szCmd[MAX_PATH * 2];
        lstrcpyA(szCmd, cmd);
    
        PROCESS_INFORMATION ProcInfo = {0};
        STARTUPINFOA si = {0};
    
        si.cb = sizeof(si);
    
        if (bHide)
        {
            si.dwFlags = STARTF_USESHOWWINDOW;
            si.wShowWindow = SW_HIDE;
        }//if
    
        BOOL bSuccess;
        bSuccess = CreateProcessA(0, szCmd, 0, 0, FALSE, 0, 0, 0, &si, &ProcInfo); 
        if (!bSuccess)
        {
            LogMessage(L"CreateProcess(%s) failed, le = %u", cmd, GetLastError()); 
            return false;
        }//if
    
        if (pi)
        {
            // caller is responsible for closing handles
            *pi = ProcInfo;
        }//if
        else
        {
            CloseHandle(ProcInfo.hThread);
            CloseHandle(ProcInfo.hProcess);
        }//else
    
        return true;
    }//run
    gg

  14. #14
    Registered User
    Join Date
    Mar 2005
    Location
    Mountaintop, Pa
    Posts
    1,058
    The following works for me...

    Code:
    #include <windows.h>
    #include <strsafe.h>
    
    BOOL ExecuteCommand(LPCTSTR szInputCommand)
    {
    	TCHAR szComSpec[MAX_PATH];
    	TCHAR szCommand[2048];
    	STARTUPINFO si;
    	PROCESS_INFORMATION pi = { 0 };
    
    	si.cb = sizeof( si );
    	si.lpReserved = NULL;
    	si.dwFlags = 0;
    	si.cbReserved2 = 0;
    	si.lpReserved2 = NULL; 
    	si.lpDesktop = NULL;
    	si.lpTitle = NULL;
    	si.dwX = 0;
    	si.dwY = 0;
    	si.dwXSize = 0;
    	si.dwYSize = 0;
    	si.dwXCountChars = 0;                        
    	si.dwYCountChars = 0;
    	si.dwFillAttribute = 0;
    	si.dwFlags = 0;
    	si.wShowWindow = 0;
    	si.hStdInput = NULL;
    	si.hStdOutput = NULL;
    	si.hStdError = NULL;
    
    	if ( SUCCEEDED(StringCchPrintf(szCommand, sizeof(szCommand)/sizeof((szCommand)[0]), TEXT("/c %s"), szInputCommand)) &&
    		GetEnvironmentVariable(TEXT("COMSPEC"), szComSpec, sizeof(szComSpec)/sizeof((szComSpec)[0])) && 
    		CreateProcess(szComSpec, szCommand, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi) )
    	{
    		WaitForSingleObject(pi.hProcess, INFINITE);
    		CloseHandle(pi.hThread);
    		CloseHandle(pi.hProcess);
    		return TRUE;
    	}
    	return FALSE;
    }
    
    INT main(VOID)
    {
    	ExecuteCommand("subst R: C:\\Progra~1\\Syntegra");  /*  This WORKS!!!! */
    //	ExecuteCommand("subst R: C:\\Program Files\\Syntegra"); /*  This does NOT work!! */
    //	ExecuteCommand("subst R: /D");  /* Delete the R: drive */
    	return 0;
    }

  15. #15
    'Allo, 'Allo, Allo
    Join Date
    Apr 2008
    Posts
    639
    Quote Originally Posted by 1inmillion View Post
    Now my only question is how I am getting err 183, even though I am not able to see the drive R: in “MyComputer”.
    You can use the reciprical function QueryDosDevice to see what Windows thinks its mapped to. Also if your app is a service that isn't running under the LocalSystem/SYSTEM acount, then any mappings will be local to the service's user account and not global. That is, the service may succeed in creating the mapping but as an interactive user you may not see it in My Computer. There's more info, and the scoping rules for various Windows versions here

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. CreateProcess going away indefinitely
    By khartley in forum C++ Programming
    Replies: 9
    Last Post: 12-31-2003, 10:14 AM
  2. working out...
    By TechWins in forum A Brief History of Cprogramming.com
    Replies: 11
    Last Post: 04-10-2003, 10:20 AM
  3. cygwin -> unix , my code not working properly ;(
    By CyC|OpS in forum C Programming
    Replies: 4
    Last Post: 05-18-2002, 04:08 AM
  4. getting current working filename
    By Unregistered in forum C++ Programming
    Replies: 1
    Last Post: 04-17-2002, 03:42 PM
  5. What ive been working one, GL related
    By Eber Kain in forum Game Programming
    Replies: 3
    Last Post: 10-15-2001, 09:20 AM

Tags for this Thread