2

I have the following code:

#include <windows.h>
#include <stdio.h>
#include <shlwapi.h>

#pragma comment ( lib, "shlwapi.lib" )

int __cdecl wmain( int argc, PWSTR argv[] )
{
HANDLE Job( CreateJobObject( NULL, NULL ) );
if( !Job )
{
    wprintf( L"Could not create job object, error %d\n", GetLastError() );
    return 0;
}

HANDLE IOPort( CreateIoCompletionPort( INVALID_HANDLE_VALUE, NULL, 0, 1 ) );
if( !IOPort )
{
    wprintf( L"Could not create IO completion port, error %d\n", GetLastError() );
    return 0;
}

JOBOBJECT_ASSOCIATE_COMPLETION_PORT Port;
Port.CompletionKey = Job;
Port.CompletionPort = IOPort;

if( !SetInformationJobObject( Job, JobObjectAssociateCompletionPortInformation, &Port, sizeof( Port ) ) )
{
    wprintf( L"Could not associate job with IO completion port, error %d\n", GetLastError() );
    return 0;
}

PROCESS_INFORMATION ProcessInformation;
STARTUPINFO StartupInfo = { sizeof(StartupInfo) };
PWSTR CommandLine = PathGetArgs(GetCommandLine());

if( !CreateProcess( NULL, CommandLine, NULL, NULL, FALSE, CREATE_NEW_CONSOLE | CREATE_SUSPENDED, NULL, NULL, &StartupInfo, &ProcessInformation ) )
{
    wprintf( L"Could not run process, error %d\n", GetLastError() );
    return 0;
}

if( !AssignProcessToJobObject( Job, ProcessInformation.hProcess ) )
{
    wprintf( L"Could not assign process to job, error %d\n", GetLastError() );
    return 0;
}

ResumeThread( ProcessInformation.hThread );
CloseHandle( ProcessInformation.hThread );
CloseHandle( ProcessInformation.hProcess );

DWORD CompletionCode;
ULONG_PTR CompletionKey;
LPOVERLAPPED Overlapped;

int ProcessCount = 0;

while ( GetQueuedCompletionStatus( IOPort, &CompletionCode, &CompletionKey, &Overlapped, INFINITE ) && CompletionCode != JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO )
{
    if ( CompletionCode == JOB_OBJECT_MSG_NEW_PROCESS ) ProcessCount++;
    if ( ( CompletionCode == JOB_OBJECT_MSG_EXIT_PROCESS ) || ( CompletionCode == JOB_OBJECT_MSG_ABNORMAL_EXIT_PROCESS) ) ProcessCount--;

    wprintf( L"Waiting for %d processes to finish...\n", ProcessCount );
}

wprintf( L"All done\n" );

return 0;
}

This code works fine on Windows 7, but AssignProcessToJobObject fails With error code 5 ( Access Denied ) on Windows XP. According to MSDN: Windows 7, Windows Server 2008 R2, Windows XP with SP3, Windows Server 2008, Windows Vista, and Windows Server 2003: The process must not already be assigned to a job; if it is, the function fails with ERROR_ACCESS_DENIED. This behavior changed starting in Windows 8 and Windows Server 2012.

Could someone please help me to correct this code?

Thanks!

Update: I was able to find the problem, but i still don't know how to solve it :( The problem is, that is i log in an XP machine, with a standard user( no admin rights), and open a cmd with runas(with a user who has admin rights), then this cmd will be created as ajobobject. In process explorer you can see this. If i want to start my application from this cmd, then AssignProcessToJobObject will fail with erro Access denies, because thios cmd is already assigned to a job.

Is there a way to solve my problem?

kampi
  • 2,362
  • 12
  • 52
  • 91
  • Future readers should refer to http://stackoverflow.com/questions/13471611/how-to-detach-a-process-from-a-jobobject/13485946#13485946; I've moved my answer to there since it is more appropriate. – Harry Johnston Nov 21 '12 at 03:36

1 Answers1

2

It could be that the environment in which the code is running has already created a job which the parent process is included in. You could try adding CREATE_BREAKAWAY_FROM_JOB to the process creation flags as may allow the new process to break from the job that it is currently in.

I can't remember if Visual Studio runs stuff in a job when it runs things under the debugger.

You could also try querying the current processes job status as this will show if it's already in a job .

Len Holgate
  • 21,282
  • 4
  • 45
  • 92
  • Please read my update. Do you have any other idee how to solve my problem, knowing the updates? – kampi Nov 20 '12 at 10:05
  • Have you tried dumping out the details of the job you're in? Have you tried adding `CREATE_BREAKAWAY_FROM_JOB` to the process creation flags? – Len Holgate Nov 20 '12 at 15:17
  • I1m checking which information should i query. I tried to use CREATE_BREAKAWAY_FROM_JOB but then createprocess fails with access denied. – kampi Nov 20 '12 at 15:39
  • If the job that you're in doesn't allow you to break away then you are stuck. I assume it works correctly if you run as administrator directly? – Len Holgate Nov 20 '12 at 16:54
  • That's what i afraid of. If i open a cmd under SYSTEM account, and start my app from there, then it works fine. Another solution would be if i could create a process under SYSTEM account(if possible without using a service), but i don't know how to do that. Just to be clear, this happenes only under XP. Under Windows 7 it works perfectely. – kampi Nov 20 '12 at 18:17