Τρόπος κατάργησης πληροφοριών μητρώου για τις συσκευές που θα ποτέ να χρησιμοποιηθούν ξανά σε έναν υπολογιστή που εκτελεί Windows Server 2003 ή νεότερη έκδοση

ΕΙΣΑΓΩΓΗ

Σε έναν υπολογιστή που εκτελεί Windows Server 2003 ή νεότερη έκδοση των Windows, μπορεί να συνδέεται μια συσκευή αποθήκευσης που είναι συνδεδεμένη μέσω καναλιού οπτικών ινών ή το πρωτόκολλο iSCSI για μόνο ένα μικρό χρονικό διάστημα. Όταν συνδέεται μια συσκευή αποθήκευσης, τα Windows δημιουργούν πληροφορίες μητρώου για τη συσκευή. Με τον καιρό, το μητρώο μπορεί να περιέχει πολλές εγγραφές για συσκευές που πρόκειται να χρησιμοποιηθεί ποτέ ξανά. Αυτό το άρθρο περιγράφει τον τρόπο για να καταργήσετε αυτές τις πληροφορίες από το μητρώο του συστήματος.

Περισσότερες πληροφορίες

Όταν μια νέα συσκευή είναι συνδεδεμένη σε έναν υπολογιστή, τα Windows εγγραφές πληροφορίες σχετικά με τη συσκευή στο μητρώο του συστήματος. Για τις περισσότερες συσκευές, η διαδικασία αυτή δεν προκαλεί πρόβλημα. Ωστόσο, όταν μια συσκευή αποθήκευσης που παρουσιάζεται από έναν αριθμό λογικής μονάδας (LUN) μέσω καναλιού οπτικών ινών ή iSCSI, η συσκευή ενδέχεται να ποτέ να συναντήσει ξανά από τον υπολογιστή. Για παράδειγμα, μια συσκευή μπορεί να έχουν προσδιοριστεί από έναν σειριακό αριθμό ή σελίδες SCSI 0x80 και 0x83.

Σε αυτήν την περίπτωση, το μητρώο μπορεί να περιέχει καταχωρήσεις για συσκευές που μπορεί να εμφανιστεί ποτέ ξανά. Όχι μόνο κάνετε αυτές τις καταχωρήσεις, καταλαμβάνουν χώρο στο μητρώο, αυτές οι καταχωρήσεις μπορεί τελικά να προκαλέσει λειτουργικά προβλήματα. Για παράδειγμα, επειδή τα ευρετήρια για λειτουργικότητα Τοποθέτησης και Άμεσης λειτουργίας χρησιμοποιούν δεκαδικές τιμές τεσσάρων ψηφίων, ένα πρόβλημα ενδέχεται να παρουσιαστεί όταν είναι συνδεδεμένη η συσκευή 10,001.

Για να επιλύσετε αυτόν τον περιορισμό στη λειτουργία Τοποθέτησης και Άμεσης λειτουργίας, μπορείτε να καταργήσετε πληροφορίες συσκευής από το μητρώο, όταν η συσκευή είναι μια μονάδα σκληρού δίσκου που δεν υπάρχει πλέον. Μπορείτε να το κάνετε χρησιμοποιώντας το βοηθητικό πρόγραμμα Microsoft DevNodeClean .

Πώς θα κατασκευάσετε για το Windows Server 2003, Windows Server 2008, Windows Server 2008 R2 και Visual Studio 2005

Για να καθαρίσετε το μητρώο για GUID κλάσης δίσκο GUID_DEVCLASS_DISKDRIVE και για το GUID_DEVCLASS_VOLUME δίσκων GUID κλάσης, ακολουθήστε τα εξής βήματα.

Σημείωση Συνιστάται να χρησιμοποιήσετε το βοηθητικό πρόγραμμα DevNodeClean για αυτήν την εργασία. Τα ακόλουθα βήματα και παράδειγμα κώδικα στο βήμα 7 παρέχονται μόνο για ενημερωτικούς σκοπούς.
  1. Για να καλέσετε τη συνάρτηση SetupDiGetClassDevs για να λάβετε πληροφορίες για την κλάση που σχετίζεται με το GUID.
  2. Για να καλέσετε τη συνάρτηση SetupDiEnumDeviceInfo για να λάβετε πληροφορίες παρουσίας για κάθε συσκευή της τρέχουσας κλάσης.
  3. Για να καλέσετε τη συνάρτηση CM_Get_DevNode_Status για να δείτε αν τις πληροφορίες της τρέχουσας συσκευής αντιπροσωπεύει μια συσκευή που δεν υπάρχει. Καθορίστε αν η κατάσταση λειτουργίας είναι ίσο με CR_NO_SUCH_DEVINST ή να CR_NO_SUCH_VALUE.
  4. Προαιρετικά, για μια συσκευή, η απουσία καλέσετε τη συνάρτηση CM_Get_Device_ID για να αποκτήσετε το Αναγνωριστικό εμφάνισης συσκευής και για να εμφανίσετε το Αναγνωριστικό, πριν να καταργήσετε τις πληροφορίες.
  5. Για τη συσκευή που λείπει, χρησιμοποιήστε τις πληροφορίες κλάσης που αποκτήσατε στο βήμα 1 και τις πληροφορίες παρουσίας που προέκυψε στο βήμα 2. Κλήση της συνάρτησης SetupDiCallClassInstaller (DIF_REMOVE...) για να καταργήσετε τις πληροφορίες από το μητρώο.
  6. Όταν όλες οι συσκευές της τρέχουσας κλάσης έχουν υποστεί χειρισμούς, να καλέσετε τη συνάρτηση SetupDiDestroyDeviceInfoList για την εκκαθάριση.
Σημείωση Σε ορισμένα σενάρια, ενδέχεται να πρέπει να καθαρίσετε το μητρώο, όχι μόνο για τις GUID_DEVCLASS_DISKDRIVE και GUID_DEVCLASS_VOLUME δίσκων GUID κλάσης αλλά και για τα GUID_DEVCLASS_SCSIADAPTER και GUID_DEVCLASS_VOLUMESNAPSHOT δίσκων GUID κλάσης. Για να γίνει αυτό, πρέπει να αλλάξετε τον ορισμό του DiskClassesToClean στο ακόλουθο δείγμα κώδικα.

Η παρακάτω εφαρμογή κονσόλας Win32 είναι ένα παράδειγμα μιας εφαρμογής που καθαρίζει το μητρώο. Για να χρησιμοποιήσετε αυτήν την εφαρμογή, ακολουθήστε τα εξής βήματα.

Η Microsoft παρέχει παραδείγματα προγραμματισμού μόνο για επεξήγηση, χωρίς καμία εγγύηση, είτε σιωπηρή είτε ρητή. Αυτό περιλαμβάνει, ενδεικτικά, τις σιωπηρές εγγυήσεις εμπορευσιμότητας ή καταλληλότητας για συγκεκριμένο σκοπό. Αυτό το άρθρο προϋποθέτει ότι είστε εξοικειωμένοι με τη γλώσσα προγραμματισμού που παρουσιάζεται, καθώς και με τα εργαλεία που χρησιμοποιούνται για τη δημιουργία διαδικασιών και τον εντοπισμό σφαλμάτων σε αυτές. Οι μηχανικοί υποστήριξης της Microsoft μπορούν να σας εξηγήσουν τη λειτουργικότητα μιας συγκεκριμένης διαδικασίας. Ωστόσο, δεν θα τροποποιήσουν αυτά τα παραδείγματα για να παράσχουν πρόσθετες λειτουργίες, ούτε θα δημιουργήσουν διαδικασίες για να καλύψουν τις συγκεκριμένες απαιτήσεις σας.
  1. Στο Microsoft Visual Studio 2005, κάντε κλικ στο κουμπί " Δημιουργία " από το μενού αρχείο και, στη συνέχεια, κάντε κλικ στο έργο.
  2. Αναπτύξτε το στοιχείο Visual C++και, στη συνέχεια, κάντε κλικ στο κουμπί Win32.
  3. Κάντε κλικ στο κουμπί Εφαρμογή κονσόλας Win32, πληκτρολογήστε Εκκαθάριση στο πλαίσιο κειμένου " όνομα " και, στη συνέχεια, κάντε κλικ στο κουμπί OK.
  4. Κάντε κλικ στο κουμπί Τέλος στο παράθυρο διαλόγου Οδηγός εφαρμογή Win32 .
  5. Στην Εξερεύνηση λύση, αναπτύξτε Τα αρχεία προέλευσης, κάντε δεξιό κλικ στο Cleanup.cppκαι, στη συνέχεια, κάντε κλικ στο κουμπί Προβολή κώδικα.
  6. Εντοπίστε τον ακόλουθο κώδικα:
    int _tmain(int argc, _TCHAR* argv[]){
    return 0;
    }

  7. Αντικαταστήστε τον κωδικό που εντοπίσατε στο βήμα 6, με τον ακόλουθο κώδικα.
    /**************************************************************************************************/     /*                                                                                                */     
    /* Copyright (c) 2007 Microsoft Corporation. All Rights Reserved */
    /* */
    /**************************************************************************************************/

    #pragma warning( disable : 4201 ) // nonstandard extension used : nameless strut/union

    #include <windows.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <stddef.h>
    #include <tchar.h>
    #include <setupapi.h>
    #include <cfgmgr32.h>
    #include <initguid.h>
    #include <devguid.h>

    #define SIZECHARS(x) (sizeof((x))/sizeof(TCHAR))
    #define arraysize(p) (sizeof(p)/sizeof((p)[0]))

    CONST GUID *DiskClassesToClean[2] = {
    &GUID_DEVCLASS_DISKDRIVE,
    &GUID_DEVCLASS_VOLUME
    };

    /**************************************************************************************************/
    /* */
    /* The user must be member of Administrator group and must have backup and restore permissions */
    /* (SE_BACKUP_NAME and SE_RESTORE_NAME). No check for these is performed in this example. */
    /* */
    /**************************************************************************************************/
    int
    __cdecl
    main(
    IN int ArgC,
    IN char * pArgV[]
    )
    {
    HDEVINFO DeviceInfoSet;
    SP_DEVINFO_DATA DeviceInfoData;
    ULONG DevicesRemoved = 0,
    i,
    MemberIndex,
    Status,
    Problem,
    ulClassesToCleanIdx;
    BOOL bDoRemove = TRUE;
    CONFIGRET cr;
    TCHAR DeviceInstanceId[MAX_DEVICE_ID_LEN];
    OSVERSIONINFO osvi;
    const GUID ** ClassesToClean;

    //
    // Parse parameters.
    //
    for (i = 1; i < (ULONG)ArgC; i++) {
    //
    // Check for help.
    //
    if ( (lstrcmpi(pArgV[i], TEXT("-?")) == 0) ||
    (lstrcmpi(pArgV[i], TEXT("/?")) == 0) ){

    printf("\nCleanUp will remove phantom storage device nodes from this machine.\n\n");
    printf("Usage: CleanUp \n");
    printf("\twhere /n displays but does not remove the phantom devnodes.\n");
    printf("\nBackup and Restore privileges are required to run this utility.\n");
    return 0;
    }

    //
    // Check for -n, which means just list the devices that we would remove.
    //
    if ( (lstrcmpi(pArgV[i], TEXT("-n")) == 0) ||
    (lstrcmpi(pArgV[i], TEXT("/n")) == 0) ) {
    bDoRemove = FALSE;
    }
    }

    //
    // Run only on Windows XP/2003 (version 5.1) or later.
    //

    ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);

    if (!GetVersionEx(&osvi)) {
    printf("CleanUp: Unable to verify Windows version, exiting...\n");
    return -1;
    }

    if ((osvi.dwMajorVersion == 5) &&
    ((osvi.dwMinorVersion == 1) || (osvi.dwMinorVersion == 2))) {
    }
    else if (osvi.dwMajorVersion>=6) {
    }
    else
    {
    printf("CleanUp: This utility is designed to run on Windows XP/2003 and later\n");
    return -1;
    }

    ClassesToClean = DiskClassesToClean;
    ulClassesToCleanIdx = arraysize(DiskClassesToClean);

    for (i=0; (i<ulClassesToCleanIdx) && (bDoRemove); i++) {

    DeviceInfoSet = SetupDiGetClassDevs(ClassesToClean[i],
    NULL,
    NULL,
    0
    );

    if (INVALID_HANDLE_VALUE!=DeviceInfoSet) {

    DeviceInfoData.cbSize = sizeof(DeviceInfoData);
    MemberIndex = 0;

    while (SetupDiEnumDeviceInfo(DeviceInfoSet,
    MemberIndex++,
    &DeviceInfoData
    )) {

    //
    // Determine whether this device is a phantom.
    //
    cr = CM_Get_DevNode_Status(&Status,
    &Problem,
    DeviceInfoData.DevInst,
    0
    );

    if ((cr == CR_NO_SUCH_DEVINST) ||
    (cr == CR_NO_SUCH_VALUE)) {
    //
    // This is a phantom. Now get the DeviceInstanceId so we
    // can display this as output, then delete the phantom if requested.
    //
    if (CM_Get_Device_ID(DeviceInfoData.DevInst,
    DeviceInstanceId,
    SIZECHARS(DeviceInstanceId),
    0) == CR_SUCCESS) {

    if (bDoRemove) {
    printf("DevNodePhantomCleaner: %s will be removed.\n",
    DeviceInstanceId);

    //
    // Call DIF_REMOVE to remove the device's hardware
    // and software registry keys.
    //
    if (SetupDiCallClassInstaller(DIF_REMOVE,
    DeviceInfoSet,
    &DeviceInfoData
    )) {
    DevicesRemoved++;
    } else {
    printf("CleanUp: Error 0x%X removing phantom\n",
    GetLastError);
    }
    } else {
    printf("CleanUp: %s would have been removed.\n",
    DeviceInstanceId);
    }
    }
    }
    }

    SetupDiDestroyDeviceInfoList(DeviceInfoSet);
    }
    }

    return DevicesRemoved;
    }
  8. Κάντε κλικ στο μενού " Εντοπισμός σφαλμάτων " και, στη συνέχεια, κάντε κλικ στο κουμπί Εκκίνηση εντοπισμού σφαλμάτων.

Πώς να δημιουργείτε για 2012 διακομιστή των Windows και του Visual Studio 2012

Για να δημιουργήσετε για 2012 διακομιστή των Windows και του Microsoft Visual Studio 2012, ακολουθήστε τα εξής βήματα.

Σημείωση Συνιστάται να χρησιμοποιήσετε το βοηθητικό πρόγραμμα DevNodeClean για αυτήν την εργασία. Τα ακόλουθα βήματα και παράδειγμα κώδικα στο βήμα 7 παρέχονται μόνο για ενημερωτικούς σκοπούς.
  1. Στο Microsoft Visual Studio 2012, κάντε κλικ στο κουμπί " Δημιουργία " από το μενού αρχείο και, στη συνέχεια, κάντε κλικ στο έργο.
  2. Στο πλαίσιο διαλόγου " Νέο έργο ", πληκτρολογήστε Εκκαθάριση στο πεδίο " όνομα " και, στη συνέχεια, κάντε διπλό κλικ στο Έργο του Win32.
  3. Στον Οδηγό εφαρμογή Win32, κάντε κλικ στο κουμπί Επόμενο.
  4. Στην περιοχή τύπος εφαρμογής, κάντε κλικ στην επιλογή Εφαρμογής κονσόλαςκαι, στη συνέχεια, κάντε κλικ στο κουμπί Τέλος.
  5. Στην Εξερεύνηση λύση, αναπτύξτε Τα αρχεία προέλευσης, κάντε δεξιό κλικ στο Cleanup.cppκαι, στη συνέχεια, κάντε κλικ στο κουμπί Προβολή κώδικα.
  6. Εντοπίστε τον ακόλουθο κώδικα:
    int _tmain(int argc, _TCHAR* argv[]){
    return 0;
    }

  7. Αντικαταστήστε τον κωδικό που εντοπίσατε στο βήμα 6, με τον ακόλουθο κώδικα.
    //DevPhantomClnr.cpp : Defines the entry point for the console application.// 

    #include "stdafx.h"

    /**************************************************************************************************/
    /* */
    /* Copyright (c) 2007 Microsoft Corporation. All Rights Reserved */
    /* */
    /**************************************************************************************************/

    #pragma warning( disable : 4201 ) // nonstandard extension used : nameless strut/union

    #include <windows.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <stddef.h>
    #include <tchar.h>
    #include <setupapi.h>
    #include <cfgmgr32.h>
    #include <initguid.h>
    #include <devguid.h>

    #define SIZECHARS(x) (sizeof((x))/sizeof(TCHAR))
    #define arraysize(p) (sizeof(p)/sizeof((p)[0]))

    CONST GUID *DiskClassesToClean[2] = {
    &GUID_DEVCLASS_DISKDRIVE,
    &GUID_DEVCLASS_VOLUME
    };

    /**************************************************************************************************/
    /* */
    /* The user must be member of Administrator group and must have backup and restore permissions */
    /* (SE_BACKUP_NAME and SE_RESTORE_NAME). No check for these is performed in this example. */
    /* */
    /**************************************************************************************************/
    int
    __cdecl
    main(
    IN int ArgC,
    IN LPCWSTR pArgV[]
    )
    {
    HDEVINFO DeviceInfoSet;
    SP_DEVINFO_DATA DeviceInfoData;
    ULONG DevicesRemoved = 0,
    i,
    MemberIndex,
    Status,
    Problem,
    ulClassesToCleanIdx;
    BOOL bDoRemove = TRUE;
    CONFIGRET cr;
    TCHAR DeviceInstanceId[MAX_DEVICE_ID_LEN];
    OSVERSIONINFO osvi;
    const GUID ** ClassesToClean;

    //
    // Parse parameters.
    //
    for (i = 1; i < (ULONG)ArgC; i++) {
    //
    // Check for help.
    //
    if ( (lstrcmpi(pArgV[i], L"-?") == 0) ||
    (lstrcmpi(pArgV[i], L"/?") == 0) ){

    printf("\nDevNodePhantomCleaner will remove phantom storage device nodes from this machine.\n\n");
    printf("Usage: nDevNodePhantomCleaner \n");
    printf("\tWhere /n displays but does not remove the phantom devnodes.\n");
    printf("\nBackup and Restore privileges are required to run this utility.\n");
    return 0;
    }

    //
    // Check for -n, which means just list the devices that we would remove.
    //
    if ( (lstrcmpi(pArgV[i], L"-n") == 0) ||
    (lstrcmpi(pArgV[i], L"/n") == 0) ) {
    bDoRemove = FALSE;
    }
    }

    //
    // Run only on Windows XP/2003 (version 5.1) or later.
    //

    ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);

    if (!GetVersionEx(&osvi)) {
    printf("DevNodePhantomCleaner: Unable to verify Windows version, exiting...\n");
    return -1;
    }

    if ((osvi.dwMajorVersion == 5) &&
    ((osvi.dwMinorVersion == 1) || (osvi.dwMinorVersion == 2))) {

    // 5.1 || 5.2

    }

    else if (osvi.dwMajorVersion>=6) {

    //Nothing special on 6.x

    }

    else
    {
    printf("DevNodePhantomCleaner: This utility is designed to run on Windows XP/2003 and later\n");
    return -1;
    }

    ClassesToClean = DiskClassesToClean;
    ulClassesToCleanIdx = arraysize(DiskClassesToClean);

    for (i=0; (i<ulClassesToCleanIdx) && (bDoRemove); i++) {

    DeviceInfoSet = SetupDiGetClassDevs(ClassesToClean[i],
    NULL,
    NULL,
    0
    );

    if (INVALID_HANDLE_VALUE!=DeviceInfoSet) {

    DeviceInfoData.cbSize = sizeof(DeviceInfoData);
    MemberIndex = 0;

    while (SetupDiEnumDeviceInfo(DeviceInfoSet,
    MemberIndex++,
    &DeviceInfoData
    )) {

    //
    // Determine whether this device is a phantom.
    //
    cr = CM_Get_DevNode_Status(&Status,
    &Problem,
    DeviceInfoData.DevInst,
    0
    );

    if ((cr == CR_NO_SUCH_DEVINST) ||
    (cr == CR_NO_SUCH_VALUE)) {
    //
    // This is a phantom. Now get the DeviceInstanceId so we
    // can display this as output, then delete the phantom if requested.
    //
    if (CM_Get_Device_ID(DeviceInfoData.DevInst,
    DeviceInstanceId,
    SIZECHARS(DeviceInstanceId),
    0) == CR_SUCCESS) {

    if (bDoRemove) {
    printf("DevNodePhantomCleaner: %ws will be removed.\n",
    DeviceInstanceId);

    //
    // Call DIF_REMOVE to remove the device's hardware
    // and software registry keys.
    //
    if (SetupDiCallClassInstaller(DIF_REMOVE,
    DeviceInfoSet,
    &DeviceInfoData
    )) {
    DevicesRemoved++;
    } else {
    printf("DevNodePhantomCleaner: Error 0x%x removing phantom\n",
    GetLastError());
    }
    } else {
    printf("DevNodePhantomCleaner: %ws would have been removed.\n",
    DeviceInstanceId);
    }
    }
    }
    }

    SetupDiDestroyDeviceInfoList(DeviceInfoSet);
    }
    }

    return DevicesRemoved;
    }
  8. Στην Εξερεύνηση λύσεων, κάντε δεξιό κλικ στο Εκκαθάρισηκαι, στη συνέχεια, κάντε κλικ στο κουμπί Ιδιότητες.
  9. Ανάπτυξη Ιδιοτήτων ρύθμισης παραμέτρων, αναπτύξτε το πρόγραμμα σύνδεσηςκαι, στη συνέχεια, κάντε κλικ στο κουμπί εισόδου.
  10. Επιλέξτε Επιπλέον εξαρτήσεις, κάντε κλικ στο κάτω βέλος και στη συνέχεια επιλέξτε Επεξεργασία.
  11. Στο παράθυρο διαλόγου Επιπλέον εξαρτήσεις , τύπου setupapi.lib και cfgmgr32.lib.
  12. Κάντε κλικ στο κουμπί OK δύο φορές.
  13. Δημιουργήστε το έργο.

Ιδιότητες

Αναγνωριστικό άρθρου: 934234 - Τελευταία αναθεώρηση: 14 Ιαν 2017 - Αναθεώρηση: 1

Σχόλια