jdk

Форк
0
/
VirtualMachineImpl.c 
653 строки · 20.9 Кб
1
/*
2
 * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved.
3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
 *
5
 * This code is free software; you can redistribute it and/or modify it
6
 * under the terms of the GNU General Public License version 2 only, as
7
 * published by the Free Software Foundation.  Oracle designates this
8
 * particular file as subject to the "Classpath" exception as provided
9
 * by Oracle in the LICENSE file that accompanied this code.
10
 *
11
 * This code is distributed in the hope that it will be useful, but WITHOUT
12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14
 * version 2 for more details (a copy is included in the LICENSE file that
15
 * accompanied this code).
16
 *
17
 * You should have received a copy of the GNU General Public License version
18
 * 2 along with this work; if not, write to the Free Software Foundation,
19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
 *
21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
 * or visit www.oracle.com if you need additional information or have any
23
 * questions.
24
 */
25

26
#include "jni_util.h"
27

28
#include <windows.h>
29
#include <Sddl.h>
30
#include <string.h>
31

32
#include "sun_tools_attach_VirtualMachineImpl.h"
33

34
/* kernel32 */
35
typedef HINSTANCE (WINAPI* GetModuleHandleFunc) (LPCTSTR);
36
typedef FARPROC (WINAPI* GetProcAddressFunc)(HMODULE, LPCSTR);
37

38
/* only on Windows 64-bit or 32-bit application running under WOW64 */
39
typedef BOOL (WINAPI *IsWow64ProcessFunc) (HANDLE, PBOOL);
40

41
static GetModuleHandleFunc _GetModuleHandle;
42
static GetProcAddressFunc _GetProcAddress;
43
static IsWow64ProcessFunc _IsWow64Process;
44

45
/* psapi */
46
typedef BOOL  (WINAPI *EnumProcessModulesFunc)  (HANDLE, HMODULE *, DWORD, LPDWORD );
47
typedef DWORD (WINAPI *GetModuleFileNameExFunc) ( HANDLE, HMODULE, LPTSTR, DWORD );
48

49
/* exported function in target VM */
50
typedef jint (WINAPI* EnqueueOperationFunc)
51
    (const char* cmd, const char* arg1, const char* arg2, const char* arg3, const char* pipename);
52

53
/* OpenProcess with SE_DEBUG_NAME privilege */
54
static HANDLE
55
doPrivilegedOpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId);
56

57
/* Converts jstring to C string, returns JNI_FALSE if the string has been truncated. */
58
static jboolean jstring_to_cstring(JNIEnv* env, jstring jstr, char* cstr, size_t cstr_buf_size);
59

60

61
/*
62
 * Data copied to target process
63
 */
64

65
#define MAX_LIBNAME_LENGTH      16
66
#define MAX_FUNC_LENGTH         32
67
#define MAX_CMD_LENGTH          16
68
#define MAX_ARG_LENGTH          1024
69
#define MAX_ARGS                3
70
#define MAX_PIPE_NAME_LENGTH    256
71

72
typedef struct {
73
   GetModuleHandleFunc _GetModuleHandle;
74
   GetProcAddressFunc _GetProcAddress;
75
   char jvmLib[MAX_LIBNAME_LENGTH];         /* "jvm.dll" */
76
   char func1[MAX_FUNC_LENGTH];
77
   char func2[MAX_FUNC_LENGTH];
78
   char cmd[MAX_CMD_LENGTH + 1];            /* "load", "dump", ...      */
79
   char arg[MAX_ARGS][MAX_ARG_LENGTH + 1];  /* arguments to command     */
80
   char pipename[MAX_PIPE_NAME_LENGTH + 1];
81
} DataBlock;
82

83
/*
84
 * Return codes from enqueue function executed in target VM
85
 */
86
#define ERR_OPEN_JVM_FAIL           200
87
#define ERR_GET_ENQUEUE_FUNC_FAIL   201
88

89
/*
90
 * Declare library specific JNI_Onload entry if static build
91
 */
92
DEF_STATIC_JNI_OnLoad
93

94
/*
95
 * Code copied to target process
96
 */
97
#pragma check_stack (off)
98
/* Switch off all runtime checks (checks caused by /RTC<x>). They cause the
99
 * generated code to contain relative jumps to check functions which make
100
 * the code position dependent. */
101
#pragma runtime_checks ("scu", off)
102
DWORD WINAPI jvm_attach_thread_func(DataBlock *pData)
103
{
104
    HINSTANCE h;
105
    EnqueueOperationFunc addr;
106

107
    h = pData->_GetModuleHandle(pData->jvmLib);
108
    if (h == NULL) {
109
        return ERR_OPEN_JVM_FAIL;
110
    }
111

112
    addr = (EnqueueOperationFunc)(pData->_GetProcAddress(h, pData->func1));
113
    if (addr == NULL) {
114
        addr = (EnqueueOperationFunc)(pData->_GetProcAddress(h, pData->func2));
115
    }
116
    if (addr == NULL) {
117
        return ERR_GET_ENQUEUE_FUNC_FAIL;
118
    }
119

120
    /* "null" command - does nothing in the target VM */
121
    if (pData->cmd[0] == '\0') {
122
        return 0;
123
    } else {
124
        return (*addr)(pData->cmd, pData->arg[0], pData->arg[1], pData->arg[2], pData->pipename);
125
    }
126
}
127

128
/* This function marks the end of jvm_attach_thread_func. */
129
void jvm_attach_thread_func_end (void) {
130
}
131
#pragma check_stack
132
#pragma runtime_checks ("scu", restore)
133

134
/*
135
 * Class:     sun_tools_attach_VirtualMachineImpl
136
 * Method:    init
137
 * Signature: ()V
138
 */
139
JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_init
140
  (JNIEnv *env, jclass cls)
141
{
142
    // All following APIs exist on Windows XP with SP2/Windows Server 2008
143
    _GetModuleHandle = (GetModuleHandleFunc)GetModuleHandle;
144
    _GetProcAddress = (GetProcAddressFunc)GetProcAddress;
145
    _IsWow64Process = (IsWow64ProcessFunc)IsWow64Process;
146
}
147

148

149
/*
150
 * Class:     sun_tools_attach_VirtualMachineImpl
151
 * Method:    generateStub
152
 * Signature: ()[B
153
 */
154
JNIEXPORT jbyteArray JNICALL Java_sun_tools_attach_VirtualMachineImpl_generateStub
155
  (JNIEnv *env, jclass cls)
156
{
157
    /*
158
     * We should replace this with a real stub generator at some point
159
     */
160
    DWORD len;
161
    jbyteArray array;
162

163
    len = (DWORD)((LPBYTE) jvm_attach_thread_func_end - (LPBYTE) jvm_attach_thread_func);
164
    array= (*env)->NewByteArray(env, (jsize)len);
165
    if (array != NULL) {
166
        (*env)->SetByteArrayRegion(env, array, 0, (jint)len, (jbyte*)&jvm_attach_thread_func);
167
    }
168
    return array;
169
}
170

171
/*
172
 * Class:     sun_tools_attach_VirtualMachineImpl
173
 * Method:    openProcess
174
 * Signature: (I)J
175
 */
176
JNIEXPORT jlong JNICALL Java_sun_tools_attach_VirtualMachineImpl_openProcess
177
  (JNIEnv *env, jclass cls, jint pid)
178
{
179
    HANDLE hProcess = NULL;
180

181
    if (pid == (jint) GetCurrentProcessId()) {
182
        /* process is attaching to itself; get a pseudo handle instead */
183
        hProcess = GetCurrentProcess();
184
        /* duplicate the pseudo handle so it can be used in more contexts */
185
        if (DuplicateHandle(hProcess, hProcess, hProcess, &hProcess,
186
                PROCESS_ALL_ACCESS, FALSE, 0) == 0) {
187
            /*
188
             * Could not duplicate the handle which isn't a good sign,
189
             * but we'll try again with OpenProcess() below.
190
             */
191
            hProcess = NULL;
192
        }
193
    }
194

195
    if (hProcess == NULL) {
196
        /*
197
         * Attempt to open process. If it fails then we try to enable the
198
         * SE_DEBUG_NAME privilege and retry.
199
         */
200
        hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
201
        if (hProcess == NULL && GetLastError() == ERROR_ACCESS_DENIED) {
202
            hProcess = doPrivilegedOpenProcess(PROCESS_ALL_ACCESS, FALSE,
203
                           (DWORD)pid);
204
        }
205

206
        if (hProcess == NULL) {
207
            if (GetLastError() == ERROR_INVALID_PARAMETER) {
208
                JNU_ThrowIOException(env, "no such process");
209
            } else {
210
                char err_mesg[255];
211
                /* include the last error in the default detail message */
212
                snprintf(err_mesg, sizeof(err_mesg), "OpenProcess(pid=%d) failed; LastError=0x%x",
213
                    (int)pid, (int)GetLastError());
214
                JNU_ThrowIOExceptionWithLastError(env, err_mesg);
215
            }
216
            return (jlong)0;
217
        }
218
    }
219

220
    /*
221
     * On Windows 64-bit we need to handle 32-bit tools trying to attach to 64-bit
222
     * processes (and visa versa). X-architecture attaching is currently not supported
223
     * by this implementation.
224
     */
225
    if (_IsWow64Process != NULL) {
226
        BOOL isCurrent32bit, isTarget32bit;
227
        (*_IsWow64Process)(GetCurrentProcess(), &isCurrent32bit);
228
        (*_IsWow64Process)(hProcess, &isTarget32bit);
229

230
        if (isCurrent32bit != isTarget32bit) {
231
            CloseHandle(hProcess);
232
            #ifdef _WIN64
233
              JNU_ThrowByName(env, "com/sun/tools/attach/AttachNotSupportedException",
234
                  "Unable to attach to 32-bit process running under WOW64");
235
            #else
236
              JNU_ThrowByName(env, "com/sun/tools/attach/AttachNotSupportedException",
237
                  "Unable to attach to 64-bit process");
238
            #endif
239
        }
240
    }
241

242
    return (jlong)hProcess;
243
}
244

245

246
/*
247
 * Class:     sun_tools_attach_VirtualMachineImpl
248
 * Method:    closeProcess
249
 * Signature: (J)V
250
 */
251
JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_closeProcess
252
  (JNIEnv *env, jclass cls, jlong hProcess)
253
{
254
    CloseHandle((HANDLE)hProcess);
255
}
256

257

258
/*
259
 * Class:     sun_tools_attach_VirtualMachineImpl
260
 * Method:    createPipe
261
 * Signature: (Ljava/lang/String;)J
262
 */
263
JNIEXPORT jlong JNICALL Java_sun_tools_attach_VirtualMachineImpl_createPipe
264
  (JNIEnv *env, jclass cls, jstring pipename)
265
{
266
    HANDLE hPipe;
267
    char name[MAX_PIPE_NAME_LENGTH];
268

269
    SECURITY_ATTRIBUTES sa;
270
    LPSECURITY_ATTRIBUTES lpSA = NULL;
271
    // Custom Security Descriptor is required here to "get" Medium Integrity Level.
272
    // In order to allow Medium Integrity Level clients to open
273
    // and use a NamedPipe created by an High Integrity Level process.
274
    TCHAR *szSD = TEXT("D:")                  // Discretionary ACL
275
                  TEXT("(A;OICI;GRGW;;;WD)")  // Allow read/write to Everybody
276
                  TEXT("(A;OICI;GA;;;SY)")    // Allow full control to System
277
                  TEXT("(A;OICI;GA;;;BA)");   // Allow full control to Administrators
278

279
    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
280
    sa.bInheritHandle = FALSE;
281
    sa.lpSecurityDescriptor = NULL;
282

283
    if (ConvertStringSecurityDescriptorToSecurityDescriptor
284
          (szSD, SDDL_REVISION_1, &(sa.lpSecurityDescriptor), NULL)) {
285
        lpSA = &sa;
286
    }
287

288
    jstring_to_cstring(env, pipename, name, MAX_PIPE_NAME_LENGTH);
289

290
    hPipe = CreateNamedPipe(
291
          name,                         // pipe name
292
          PIPE_ACCESS_INBOUND,          // read access
293
          PIPE_TYPE_BYTE |              // byte mode
294
            PIPE_READMODE_BYTE |
295
            PIPE_WAIT,                  // blocking mode
296
          1,                            // max. instances
297
          128,                          // output buffer size
298
          8192,                         // input buffer size
299
          NMPWAIT_USE_DEFAULT_WAIT,     // client time-out
300
          lpSA);        // security attributes
301

302
    LocalFree(sa.lpSecurityDescriptor);
303

304
    if (hPipe == INVALID_HANDLE_VALUE) {
305
        JNU_ThrowIOExceptionWithLastError(env, "CreateNamedPipe failed");
306
    }
307
    return (jlong)hPipe;
308
}
309

310
/*
311
 * Class:     sun_tools_attach_VirtualMachineImpl
312
 * Method:    closePipe
313
 * Signature: (J)V
314
 */
315
JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_closePipe
316
  (JNIEnv *env, jclass cls, jlong hPipe)
317
{
318
    CloseHandle((HANDLE)hPipe);
319
}
320

321
/*
322
 * Class:     sun_tools_attach_VirtualMachineImpl
323
 * Method:    connectPipe
324
 * Signature: (J)V
325
 */
326
JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_connectPipe
327
  (JNIEnv *env, jclass cls, jlong hPipe)
328
{
329
    BOOL fConnected;
330

331
    fConnected = ConnectNamedPipe((HANDLE)hPipe, NULL) ?
332
        TRUE : (GetLastError() == ERROR_PIPE_CONNECTED);
333
    if (!fConnected) {
334
        JNU_ThrowIOExceptionWithLastError(env, "ConnectNamedPipe failed");
335
    }
336
}
337

338
/*
339
 * Class:     sun_tools_attach_VirtualMachineImpl
340
 * Method:    readPipe
341
 * Signature: (J[BII)I
342
 */
343
JNIEXPORT jint JNICALL Java_sun_tools_attach_VirtualMachineImpl_readPipe
344
  (JNIEnv *env, jclass cls, jlong hPipe, jbyteArray ba, jint off, jint baLen)
345
{
346
    unsigned char buf[128];
347
    DWORD len, nread, remaining;
348
    BOOL fSuccess;
349

350
    len = sizeof(buf);
351
    remaining = (DWORD)(baLen - off);
352
    if (len > remaining) {
353
        len = remaining;
354
    }
355

356
    fSuccess = ReadFile(
357
         (HANDLE)hPipe,         // handle to pipe
358
         buf,                   // buffer to receive data
359
         len,                   // size of buffer
360
         &nread,                // number of bytes read
361
         NULL);                 // not overlapped I/O
362

363
    if (!fSuccess) {
364
        if (GetLastError() == ERROR_BROKEN_PIPE) {
365
            return (jint)-1;
366
        } else {
367
            JNU_ThrowIOExceptionWithLastError(env, "ReadFile");
368
        }
369
    } else {
370
        if (nread == 0) {
371
            return (jint)-1;        // EOF
372
        } else {
373
            (*env)->SetByteArrayRegion(env, ba, off, (jint)nread, (jbyte *)(buf));
374
        }
375
    }
376

377
    return (jint)nread;
378
}
379

380
/*
381
 * Class:     sun_tools_attach_VirtualMachineImpl
382
 * Method:    enqueue
383
 * Signature: (JZLjava/lang/String;[Ljava/lang/Object;)V
384
 */
385
JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_enqueue
386
  (JNIEnv *env, jclass cls, jlong handle, jbyteArray stub, jstring cmd,
387
   jstring pipename, jobjectArray args)
388
{
389
    DataBlock data;
390
    DataBlock* pData;
391
    DWORD* pCode;
392
    DWORD stubLen;
393
    HANDLE hProcess, hThread;
394
    jint argsLen, i;
395
    jbyte* stubCode;
396
    jboolean isCopy;
397

398
    /*
399
     * Setup data to copy to target process
400
     */
401
    memset(&data, 0, sizeof(data));
402
    data._GetModuleHandle = _GetModuleHandle;
403
    data._GetProcAddress = _GetProcAddress;
404

405
    strcpy(data.jvmLib, "jvm");
406
    strcpy(data.func1, "JVM_EnqueueOperation");
407
    strcpy(data.func2, "_JVM_EnqueueOperation@20");
408

409
    /*
410
     * Command and arguments
411
     */
412
    if (!jstring_to_cstring(env, cmd, data.cmd, sizeof(data.cmd))) {
413
        JNU_ThrowByName(env, "com/sun/tools/attach/AttachOperationFailedException",
414
                        "command is too long");
415
        return;
416
    }
417
    argsLen = (*env)->GetArrayLength(env, args);
418

419
    if (argsLen > 0) {
420
        if (argsLen > MAX_ARGS) {
421
            JNU_ThrowInternalError(env, "Too many arguments");
422
            return;
423
        }
424
        for (i=0; i<argsLen; i++) {
425
            jobject obj = (*env)->GetObjectArrayElement(env, args, i);
426
            if (obj == NULL) {
427
                data.arg[i][0] = '\0';
428
            } else {
429
                if (!jstring_to_cstring(env, obj, data.arg[i], sizeof(data.arg[i]))) {
430
                    JNU_ThrowByName(env, "com/sun/tools/attach/AttachOperationFailedException",
431
                                    "argument is too long");
432
                    return;
433
                }
434
            }
435
            if ((*env)->ExceptionOccurred(env)) return;
436
        }
437
    }
438
    for (i = argsLen; i < MAX_ARGS; i++) {
439
        data.arg[i][0] = '\0';
440
    }
441

442
    /* pipe name */
443
    if (!jstring_to_cstring(env, pipename, data.pipename, sizeof(data.pipename))) {
444
        JNU_ThrowByName(env, "com/sun/tools/attach/AttachOperationFailedException",
445
                        "pipe name is too long");
446
        return;
447
    }
448

449
    /*
450
     * Allocate memory in target process for data and code stub
451
     * (assumed aligned and matches architecture of target process)
452
     */
453
    hProcess = (HANDLE)handle;
454

455
    pData = (DataBlock*) VirtualAllocEx( hProcess, 0, sizeof(DataBlock), MEM_COMMIT, PAGE_READWRITE );
456
    if (pData == NULL) {
457
        JNU_ThrowIOExceptionWithLastError(env, "VirtualAllocEx failed");
458
        return;
459
    }
460
    WriteProcessMemory( hProcess, (LPVOID)pData, (LPCVOID)&data, (SIZE_T)sizeof(DataBlock), NULL );
461

462

463
    stubLen = (DWORD)(*env)->GetArrayLength(env, stub);
464
    stubCode = (*env)->GetByteArrayElements(env, stub, &isCopy);
465

466
    if ((*env)->ExceptionOccurred(env)) return;
467

468
    pCode = (PDWORD) VirtualAllocEx( hProcess, 0, stubLen, MEM_COMMIT, PAGE_EXECUTE_READWRITE );
469
    if (pCode == NULL) {
470
        JNU_ThrowIOExceptionWithLastError(env, "VirtualAllocEx failed");
471
        VirtualFreeEx(hProcess, pData, 0, MEM_RELEASE);
472
        (*env)->ReleaseByteArrayElements(env, stub, stubCode, JNI_ABORT);
473
        return;
474
    }
475
    WriteProcessMemory( hProcess, (LPVOID)pCode, (LPCVOID)stubCode, (SIZE_T)stubLen, NULL );
476
    (*env)->ReleaseByteArrayElements(env, stub, stubCode, JNI_ABORT);
477

478
    /*
479
     * Create thread in target process to execute code
480
     */
481
    hThread = CreateRemoteThread( hProcess,
482
                                  NULL,
483
                                  0,
484
                                  (LPTHREAD_START_ROUTINE) pCode,
485
                                  pData,
486
                                  0,
487
                                  NULL );
488
    if (hThread != NULL) {
489
        if (WaitForSingleObject(hThread, INFINITE) != WAIT_OBJECT_0) {
490
            JNU_ThrowIOExceptionWithLastError(env, "WaitForSingleObject failed");
491
        } else {
492
            DWORD exitCode;
493
            GetExitCodeThread(hThread, &exitCode);
494
            if (exitCode) {
495
                switch (exitCode) {
496
                    case ERR_OPEN_JVM_FAIL :
497
                        JNU_ThrowIOException(env,
498
                            "jvm.dll not loaded by target process");
499
                        break;
500
                    case ERR_GET_ENQUEUE_FUNC_FAIL :
501
                        JNU_ThrowIOException(env,
502
                            "Unable to enqueue operation: the target VM does not support attach mechanism");
503
                        break;
504
                    default : {
505
                        char errmsg[128];
506
                        snprintf(errmsg, sizeof(errmsg), "Remote thread failed for unknown reason (%d)", exitCode);
507
                        JNU_ThrowInternalError(env, errmsg);
508
                    }
509
                }
510
            }
511
        }
512
        CloseHandle(hThread);
513
    } else {
514
        if (GetLastError() == ERROR_NOT_ENOUGH_MEMORY) {
515
            //
516
            // This error will occur when attaching to a process belonging to
517
            // another terminal session. See "Remarks":
518
            // http://msdn.microsoft.com/en-us/library/ms682437%28VS.85%29.aspx
519
            //
520
            JNU_ThrowIOException(env,
521
                "Insufficient memory or insufficient privileges to attach");
522
        } else {
523
            JNU_ThrowIOExceptionWithLastError(env, "CreateRemoteThread failed");
524
        }
525
    }
526

527
    VirtualFreeEx(hProcess, pCode, 0, MEM_RELEASE);
528
    VirtualFreeEx(hProcess, pData, 0, MEM_RELEASE);
529
}
530

531
/*
532
 * Attempts to enable the SE_DEBUG_NAME privilege and open the given process.
533
 */
534
static HANDLE
535
doPrivilegedOpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId) {
536
    HANDLE hToken;
537
    HANDLE hProcess = NULL;
538
    LUID luid;
539
    TOKEN_PRIVILEGES tp, tpPrevious;
540
    DWORD retLength, error;
541

542
    /*
543
     * Get the access token
544
     */
545
    if (!OpenThreadToken(GetCurrentThread(),
546
                         TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,
547
                         FALSE,
548
                         &hToken)) {
549
        if (GetLastError() != ERROR_NO_TOKEN) {
550
            return (HANDLE)NULL;
551
        }
552

553
        /*
554
         * No access token for the thread so impersonate the security context
555
         * of the process.
556
         */
557
        if (!ImpersonateSelf(SecurityImpersonation)) {
558
            return (HANDLE)NULL;
559
        }
560
        if (!OpenThreadToken(GetCurrentThread(),
561
                             TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,
562
                             FALSE,
563
                             &hToken)) {
564
            return (HANDLE)NULL;
565
        }
566
    }
567

568
    /*
569
     * Get LUID for the privilege
570
     */
571
    if(!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid)) {
572
        error = GetLastError();
573
        CloseHandle(hToken);
574
        SetLastError(error);
575
        return (HANDLE)NULL;
576
    }
577

578
    /*
579
     * Enable the privilege
580
     */
581
    ZeroMemory(&tp, sizeof(tp));
582
    tp.PrivilegeCount = 1;
583
    tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
584
    tp.Privileges[0].Luid = luid;
585

586
    error = 0;
587
    if (AdjustTokenPrivileges(hToken,
588
                              FALSE,
589
                              &tp,
590
                              sizeof(TOKEN_PRIVILEGES),
591
                              &tpPrevious,
592
                              &retLength)) {
593
        /*
594
         * If we enabled the privilege then attempt to open the
595
         * process.
596
         */
597
        if (GetLastError() == ERROR_SUCCESS) {
598
            hProcess = OpenProcess(dwDesiredAccess, bInheritHandle, dwProcessId);
599
            if (hProcess == NULL) {
600
                error = GetLastError();
601
            }
602
        } else {
603
            error = ERROR_ACCESS_DENIED;
604
        }
605

606
        /*
607
         * Revert to the previous privileges
608
         */
609
        AdjustTokenPrivileges(hToken,
610
                              FALSE,
611
                              &tpPrevious,
612
                              retLength,
613
                              NULL,
614
                              NULL);
615
    } else {
616
        error = GetLastError();
617
    }
618

619

620
    /*
621
     * Close token and restore error
622
     */
623
    CloseHandle(hToken);
624
    SetLastError(error);
625

626
    return hProcess;
627
}
628

629
/* Converts jstring to C string, returns JNI_FALSE if the string has been truncated. */
630
static jboolean jstring_to_cstring(JNIEnv* env, jstring jstr, char* cstr, size_t cstr_buf_size) {
631
    jboolean isCopy;
632
    const char* str;
633
    jboolean result = JNI_TRUE;
634

635
    if (jstr == NULL) {
636
        cstr[0] = '\0';
637
    } else {
638
        str = JNU_GetStringPlatformChars(env, jstr, &isCopy);
639
        if ((*env)->ExceptionOccurred(env)) {
640
            return result;
641
        }
642
        if (strlen(str) >= cstr_buf_size) {
643
            result = JNI_FALSE;
644
        }
645

646
        strncpy(cstr, str, cstr_buf_size);
647
        cstr[cstr_buf_size - 1] = '\0';
648
        if (isCopy) {
649
            JNU_ReleaseStringPlatformChars(env, jstr, str);
650
        }
651
    }
652
    return result;
653
}
654

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.