DISK.CPP
///////////////////////////////////////////////////////////////////////////// 
// disk.cpp : Implementation of DLL Exports. 
// 
// This is a part of the MMC SDK. 
// Copyright (C) 1997 Microsoft Corporation 
// All rights reserved. 
// 
// This source code is only intended as a supplement to the 
// MMC SDK Reference and related 
// electronic documentation provided with the library. 
// See these sources for detailed information regarding the 
// MMC Library product. 
// 
 
// Note: Proxy/Stub Information 
//To build a separate proxy/stub DLL,  
//run nmake -f diskps.mk in the project directory. 
 
#include "stdafx.h" 
#include "resource.h" 
#include "initguid.h" 
#include "disk.h" 
 
#include "disk_i.c" 
#include "globals.h" 
#include "compdata.h" 
 
 
CComModule _Module; 
                                       // Default entry point 
BEGIN_OBJECT_MAP(ObjectMap) 
OBJECT_ENTRY(CLSID_ComponentData, CComponentData) 
END_OBJECT_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// DLL Entry Point 
 
extern "C" 
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/) 
{ 
  if ( DLL_PROCESS_ATTACH == dwReason ) 
  { 
    g_hinst = hInstance;               // Store global instance handle 
_Module.Init(ObjectMap, hInstance); 
DisableThreadLibraryCalls(hInstance); 
  } 
  else if ( DLL_PROCESS_DETACH == dwReason ) 
_Module.Term(); 
 
  return TRUE;                         // OK 
 
} // end DllMain() 
 
///////////////////////////////////////////////////////////////////////////// 
// Used to determine whether the DLL can be unloaded by OLE 
 
STDAPI DllCanUnloadNow(void) 
{ 
  return (_Module.GetLockCount()==0) ? S_OK : S_FALSE; 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// Returns a class factory to create an object of the requested type 
 
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv) 
{ 
  return _Module.GetClassObject(rclsid, riid, ppv); 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// DllRegisterServer - Adds entries to the system registry 
// If we don't get these things into the registry, then MMC will not see us 
// and we will not appear in the "Add Snapin" dialog. 
// We error check every return value in both DllRegisterServer() and 
// DllUnRegisterServer().  You may want to do this only in your debug 
// version to reduce code size, at the expense of making troubleshooting  
// more difficult 
// 
STDAPI DllRegisterServer(void) 
{ 
  HKEY hMmcParentKey  = NULL; 
  HKEY hDiskParentKey = NULL; 
  HKEY hStandAloneKey = NULL; 
  HKEY hNodeTypesKey  = NULL; 
  HKEY hTempNodeKey   = NULL; 
  LONG nErr           = 0; 
 
  //DebugBreak();                  // Uncomment this to step through registration 
 
  // Open the MMC Parent key 
  nErr = RegOpenKey( HKEY_LOCAL_MACHINE, 
                 L"Software\\Microsoft\\MMC\\SnapIns", 
         &hMmcParentKey 
       ); 
  if( ERROR_SUCCESS != nErr ) 
    DisplayError( GetLastError(), L"Open MMC Parent Key Failed" ); 
   
  // Create the ID for our ICompnentData Interface 
  // The ID was generated for us, because we used a Wizard to create the app. 
  // Take the ID for IComponentData in the IDL file. 
  // 
  //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
  // Make sure you change this if you use this code as a starting point! 
  // Change other IDs as well below! 
  //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
  nErr = RegCreateKey( hMmcParentKey, 
                   L"{CF8CC7EF-0CFE-11D1-8F07-000000000000}", 
       &hDiskParentKey 
         ); 
  if( ERROR_SUCCESS != nErr ) 
    DisplayError( GetLastError(), L"Open Disk Parent Key Failed" ); 
 
  nErr = RegSetValueEx( hDiskParentKey, 
                    L"NameString", 
            0, 
        REG_SZ, 
        (LPBYTE)L"Disk Sample", 
        sizeof(L"Disk Sample") 
          ); 
  if( ERROR_SUCCESS != nErr ) 
    DisplayError( GetLastError(), L"Set NameString Failed" ); 
 
  nErr = RegSetValueEx( hDiskParentKey, 
                    L"NodeType", 
        0, 
        REG_SZ, 
        (LPBYTE)L"{570F713A-0F57-11D1-A194-00C04FC3092F}", 
        sizeof(L"{570F713A-0F57-11D1-A194-00C04FC3092F}") 
          ); 
  if( ERROR_SUCCESS != nErr ) 
    DisplayError( GetLastError(), L"Set NodeType Failed" ); 
 
 
  // We are a stand alone snapin, so set the key for this 
  nErr = RegCreateKey( hDiskParentKey, L"StandAlone", &hStandAloneKey); 
  if( ERROR_SUCCESS != nErr ) 
    DisplayError( GetLastError(), L"Create StandAlone Key Failed" ); 
 
  // StandAlone has no children, so close it 
  nErr = RegCloseKey( hStandAloneKey );               
  if( ERROR_SUCCESS != nErr ) 
    DisplayError( GetLastError(), L"Close StandAlone Failed" ); 
 
  // Set the node types that appear in our snapin 
  nErr = RegCreateKey( hDiskParentKey, L"NodeTypes", &hNodeTypesKey ); 
  if( ERROR_SUCCESS != nErr ) 
    DisplayError( GetLastError(), L"Create NodeTypes Key Failed" ); 
 
  // Here is our root node.  Used uuidgen to get it 
  nErr = RegCreateKey( hNodeTypesKey, 
                   L"{570F713A-0F57-11D1-A194-00C04FC3092F}", 
       &hTempNodeKey 
         ); 
  if( ERROR_SUCCESS != nErr ) 
    DisplayError( GetLastError(), L"Create RootNode Key Failed" ); 
 
  nErr = RegSetValueEx( hTempNodeKey, 
                    NULL, 
            0, 
        REG_SZ, 
        (LPBYTE)L"Root Node", 
        sizeof(L"Root Node") 
          ); 
  if( ERROR_SUCCESS != nErr ) 
    DisplayError( GetLastError(), L"Set Root Node String Failed" ); 
 
  nErr = RegCloseKey( hTempNodeKey );    // Close it so we can reuse handle 
  if( ERROR_SUCCESS != nErr ) 
    DisplayError( GetLastError(), L"Close RootNode Failed" ); 
 
  // Here is our child node under the root node. Used uuidgen to get it 
  nErr = RegCreateKey( hNodeTypesKey, 
                   L"{50C4FBDC-1F02-11D1-A1AE-00C04FC3092F}", 
       &hTempNodeKey 
         ); 
  if( ERROR_SUCCESS != nErr ) 
    DisplayError( GetLastError(), L"Create Child Node Key Failed" ); 
 
  nErr = RegSetValueEx( hTempNodeKey, 
                    NULL, 
        0, 
        REG_SZ, 
        (LPBYTE)L"Child Under Root Node", 
        sizeof(L"Child Under Root Node") 
          ); 
  if( ERROR_SUCCESS != nErr ) 
    DisplayError( GetLastError(), L"Set Child Node String Failed" ); 
 
  nErr = RegCloseKey( hTempNodeKey ); 
  if( ERROR_SUCCESS != nErr ) 
    DisplayError( GetLastError(), L"Close Child Node Key Failed" ); 
 
  nErr = RegCloseKey( hNodeTypesKey  ); 
  if( ERROR_SUCCESS != nErr ) 
    DisplayError( GetLastError(), L"Close Node Types Key Failed" ); 
 
  nErr = RegCloseKey( hDiskParentKey ); 
  if( ERROR_SUCCESS != nErr ) 
    DisplayError( GetLastError(), L"Close Disk Parent Key Failed" ); 
 
  nErr = RegCloseKey( hMmcParentKey  ); 
  if( ERROR_SUCCESS != nErr ) 
    DisplayError( GetLastError(), L"Close MMC Parent Key Failed" ); 
 
  // Registers object, typelib and all interfaces in typelib 
  return _Module.RegisterServer(TRUE); 
 
} // end DllRegisterServer() 
 
 
//--------------------------------------------------------------------------- 
// DllUnregisterServer:  Since we are a good citizen, delete all the keys 
//                       we added to the MMC keys in the registry as well as 
//                       the normal unregistering of our com objects. 
// 
STDAPI DllUnregisterServer(void) 
{ 
  HKEY hMmcParentKey  = NULL;          // MMC parent key 
  HKEY hDiskParentKey = NULL;          // Our Snap-In key  - has children 
  HKEY hNodeTypesKey  = NULL;          // Our NodeType key - has children 
  LONG nErr           = 0; 
 
  // DebugBreak();                       // Uncomment this to step through UnRegister 
 
  // Open the MMC parent key 
  nErr = RegOpenKey( HKEY_LOCAL_MACHINE, 
                     L"Software\\Microsoft\\MMC\\SnapIns", 
                     &hMmcParentKey 
                   ); 
  if( ERROR_SUCCESS != nErr ) 
    DisplayError( GetLastError(), L"Open MMC Parent Key Failed"  );  
 
  // Open our Parent key 
  nErr = RegOpenKey( hMmcParentKey, 
                     L"{CF8CC7EF-0CFE-11D1-8F07-000000000000}", 
                     &hDiskParentKey 
                   ); 
  if( ERROR_SUCCESS != nErr ) 
    DisplayError( GetLastError(), L"Open Disk Parent Key Failed" ); 
   
  // Now open the NodeTypes key 
  nErr = RegOpenKey( hDiskParentKey,       // Handle of parent key 
                     L"NodeTypes",         // Name of key to open 
                     &hNodeTypesKey        // Handle to newly opened key 
                   ); 
  if( ERROR_SUCCESS != nErr ) 
     DisplayError( GetLastError(), L"Open NodeTypes Key Failed"  ); 
 
  // Delete the root node key  
  nErr = RegDeleteKey( hNodeTypesKey, L"{570F713A-0F57-11D1-A194-00C04FC3092F}" );   
  if( ERROR_SUCCESS != nErr ) 
     DisplayError( GetLastError(), L"Delete Root Node Key Failed"  ); 
 
  // Delete the child node key 
  nErr = RegDeleteKey( hNodeTypesKey, L"{50C4FBDC-1F02-11D1-A1AE-00C04FC3092F}" );   
  if( ERROR_SUCCESS != nErr ) 
    DisplayError( GetLastError(), L"Delete Child Node Key Failed"  ); 
 
  // Close the node type key so we can delete it 
  nErr = RegCloseKey( hNodeTypesKey );  
  if( ERROR_SUCCESS != nErr ) 
    DisplayError( GetLastError(), L"Close NodeTypes Key failed"  ); 
 
  // Delete the NodeTypes key 
  nErr = RegDeleteKey( hDiskParentKey, L"NodeTypes" );   
  if( ERROR_SUCCESS != nErr ) 
    DisplayError( GetLastError(), L"Delete NodeTypes Key failed"  ); 
   
  // StandAlone key has no children so we can delete it now 
  nErr = RegDeleteKey( hDiskParentKey, L"StandAlone" ); 
  if( ERROR_SUCCESS != nErr ) 
    DisplayError( GetLastError(), L"Delete StandAlone Key Failed"  );  
   
  // Close our Parent Key 
  nErr = RegCloseKey( hDiskParentKey ); 
  if( ERROR_SUCCESS != nErr ) 
    DisplayError( GetLastError(), L"Close Disk Parent Key Failed"  );  
 
  // Now we can delete our Snap-In key since the children are gone 
  nErr = RegDeleteKey( hMmcParentKey, L"{CF8CC7EF-0CFE-11D1-8F07-000000000000}" );   
  if( ERROR_SUCCESS != nErr ) 
    DisplayError( GetLastError(), L"Delete Disk Parent Key Failed"  );  
 
  nErr = RegCloseKey( hMmcParentKey ); 
  if( ERROR_SUCCESS != nErr ) 
    DisplayError( GetLastError(), L"Close MMC Parent Key Failed"  );  
 
  // UnRegisters object, typelib and all interfaces in typelib 
  return _Module.UnregisterServer(); 
 
} // end DllUnregisterServer()