5

में प्रकट नहीं होते हैं मेरे पास स्थानीय सिस्टम खाते के अंतर्गत चल रही एक Windows सेवा है जो DefineDosDevice फ़ंक्शन का उपयोग करके डॉस डिवाइस बनाता है। सेवा W2K8 रिमोट डेस्कटॉप सर्वर पर चल रही है। यदि डिवाइस सेवा के क्रेडेंशियल्स का उपयोग करके बनाए जाते हैं, तो वे ग्लोबल डिवाइस नेमस्पेस में बनाए जाते हैं और इसलिए सभी उपयोगकर्ताओं के लिए दृश्यमान होते हैं। मुझे केवल एक विशेष इंटरैक्शन सत्र में दिखाई देने वाले उपकरणों की आवश्यकता है।एक प्रतिरूपित सत्र में परिभाषित डॉस डिवाइस क्यों एक्सप्लोरर

मैं उस उपयोगकर्ता का प्रतिरूपण करके इसे पूरा करता हूं जिसके सत्र में मैं ड्राइव दिखाना चाहता हूं। यह काफी सरल है, बशर्ते सत्र आईडी उपलब्ध हो।

int _tmain(int argc, _TCHAR* argv[]) 
{ 
BOOL result = TRUE; 

if(argc > 3 && !wcscmp(argv[2], L"/i")) 
{ 
    HANDLE hToken = 0; 
    DWORD dwSessionId = _wtoi(argv[3]); 
    result = WTSQueryUserToken(dwSessionId, &hToken); 
    if(result) result = ImpersonateLoggedOnUser(hToken); 
} 
if(result) 
{ 
    LPTSTR drive = argv[1]; 
    DefineDosDevice(DDD_REMOVE_DEFINITION, drive, NULL); 
    result = DefineDosDevice(0, drive, L"C:\\test"); 
} 

if(!result) 
{ 
    printf("Error: %d\n", GetLastError()); 
} 
return 0; 
} 

इस कोड का परीक्षण करने के लिए, मैं एक सेवा है जो स्थानीय सिस्टम खाते के तहत एक आदेश खोल शुरूआत बनाया:: यह एक साधारण परीक्षण आवेदन मैं इस समस्या को वर्णन करने के लिए लिखा था है

अनुसूचित जाति test_svc binpath बनाने = " cmd/K शुरू "प्रकार = खुद type = बातचीत

यह सेवा शुरू करने के लिए विफल रहता है, लेकिन इससे पहले कि यह विफल रहता है, यह एक कमांड खोल स्थानीय सिस्टम खाते के अंतर्गत चल spawns।

स्थानीय सिस्टम cmd.exe से, मैं चलाएँ:

MySubst.exe एक्स:/मैं 2

जो ImpersonateLoggedOnUser (आह्वान), तो DefineDosDevice()

से कॉल cmd.exe उपयोगकर्ता के सत्र में चल रहा है, मैं चलाता हूं:

MySubst.exe y:

कौन सा कॉल DefineDosDevice बिना ImpersonateLoggedOnUser() का आह्वान करता है।

यह काम करता है। Cmd.exe से मैं दो ड्राइव एक्स: और वाई: तक पहुंच सकता हूं। मैं स्टार्ट मेनू से notepad.exe लॉन्च कर सकता हूं, और एक्स: और वाई: ड्राइव देख सकता हूं। इसके अलावा, अगर मैं एक अलग उपयोगकर्ता के साथ एक नया टर्मिनल सेवा सत्र बनाता हूं, तो मुझे एक्स नहीं दिखता है: या वाई:।

हालांकि, एक्सप्लोरर केवल वाई: ड्राइव को "सभी कंप्यूटर" के अंतर्गत दिखाता है। वाई: वह ड्राइव है जो लक्ष्य परीक्षण के भीतर cmd.exe से चल रहा है, मेरा परीक्षण अनुप्रयोग चलाकर बनाया गया था, यानी प्रतिरूपण नहीं किया गया था। यदि मैं कार्य प्रबंधक से explorer.exe को पुनरारंभ करता हूं, तो एक्स: और वाई: ड्राइव दोनों दिखाई देते हैं।

मैंने परिभाषित विन एनटी उपकरणों की जांच के लिए SysInternals से WinObj.exe का भी उपयोग किया। क्या मैं देख रहा हूँ है:

Global SymbolicLink \Global?? 
X:  SymbolicLink \\??\C:\test 
Y:  SymbolicLink \\??\C:\test 
:

- Sessions 
    - 0 
     - DosDevices 
      00000000-000057607 

की "00,000,000-000,057,607" कर रहे हैं सामग्री (57,607 सत्र है कि मैं नाम से कार्य कर रहा हूँ के साथ जुड़े लॉगिन सत्र की आईडी है)

WinObj के अनुसार, दो डॉस डिवाइस समान हैं। वे एक ही सत्र और लॉगऑन सत्र से संबंधित हैं। वे एक ही एनटी ऑब्जेक्ट के लिए सिम्लिंक हैं।

यह कैसे हो सकता है कि उनमें से एक एक्सप्लोरर में दिखाई दे और दूसरा नहीं।

+0

यदि आप एक्सप्लोरर को बल-छोड़कर पुनरारंभ करते हैं, तो क्या यह ड्राइव को देखता है? –

+0

सिर्फ प्रतिरूपण के साथ ऐसा करना संभव नहीं है। आपकी तरफ से बदलाव करने के लिए आपको लक्ष्य संदर्भ में वास्तविक प्रक्रिया लॉन्च करने की आवश्यकता हो सकती है। –

+0

@ हैरीजोहनस्टन एक्सप्लोरर के पुनरारंभ करने से ड्राइव्स दिखने का कारण बनता है, लेकिन मुझे यकीन नहीं है कि इससे क्या निष्कर्ष निकालना है। – FishesCycle

उत्तर

4

@arx और @ हैरी जॉनस्टन पैसे पर थे। यदि मैं एक्सप्लोरर के समान सत्र में थ्रेड से WM_DEVICECHANGE संदेश प्रसारित करता हूं, तो मेरा कंप्यूटर में नया ड्राइव दिखाई देता है। यहां कोड है:

DWORD recipients = BSM_ALLDESKTOPS | BSM_APPLICATIONS; 

DEV_BROADCAST_VOLUME msg; 
ZeroMemory(&msg, sizeof(msg)); 
msg.dbcv_size = sizeof(msg); 
msg.dbcv_devicetype = DBT_DEVTYP_VOLUME; 
msg.dbcv_unitmask = 1 << ('X' - 'A'); 

long success = BroadcastSystemMessage(0, &recipients, WM_DEVICECHANGE, DBT_DEVICEARRIVAL, (LPARAM)&msg);