mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
957 lines
27 KiB
957 lines
27 KiB
//***************************************************************************
|
|
//
|
|
// Library:
|
|
// HOMEDRV.DLL
|
|
//
|
|
//
|
|
// Author:
|
|
// Joev Dubach
|
|
//
|
|
//
|
|
// Purpose:
|
|
// HOMEDRV is a File Manager extension DLL. An extension DLL adds
|
|
// a menu to File Manager, contains entry point that processes menu
|
|
// commands and notification messages sent by File Manager, and
|
|
// queries data and information about the File Manager windows. The
|
|
// purpose of an extension DLL is to add administration support
|
|
// features to File Manager, for example, file and disk utilities.
|
|
// Up to five extension DLLs may be installed at any one time.
|
|
//
|
|
// HOMEDRV adds a menu called "HomeDrive" to File Manager and
|
|
// processes all the messages that are sent by File Manager to the
|
|
// HOMEDRV DLL. In particular, it allows the user to select
|
|
// "Connect to Home Drive" from the HomeDrive menu. Using RPC, the
|
|
// DLL asks a HomeDrive server running on NT for the home share of
|
|
// the given user. If it receives this information, it redirects
|
|
// a network drive to this share. Then it tells File Manager to
|
|
// refresh its windows, so as to bring the new connection up.
|
|
//
|
|
// Usage:
|
|
// File Manager installs the extensions that have entries in the
|
|
// [AddOns] section of the WINFILE.INI initialization file. An entry
|
|
// consists of a tag and a value. To load HOMEDRV.DLL as a File
|
|
// Manager extension, add the following to WINFILE.INI (assuming the
|
|
// DLL resides in c:\win\system32):
|
|
//
|
|
// [AddOns]
|
|
// HomeDrive Extension=c:\win\system32\homedrv.dll
|
|
//
|
|
//
|
|
// Menu Options:
|
|
// Following menu items belong to the "Extension" menu that is added
|
|
// to File Manager:
|
|
//
|
|
// Connect to Home Drive - Redirects a drive to a given user's share
|
|
// About HomeDrive... - Displays About dialog
|
|
//
|
|
//
|
|
// More Info:
|
|
// Query on-line help on: FMExtensionProc, File Manager Extensions, RPC
|
|
//
|
|
//
|
|
//***************************************************************************
|
|
|
|
//
|
|
// Inclusions
|
|
//
|
|
|
|
#include <direct.h>
|
|
#include <errno.h>
|
|
#include <windows.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include <sys\types.h>
|
|
#include <sys\stat.h>
|
|
#include <ctype.h>
|
|
#include <rpc.h> // RPC data structures and APIs
|
|
#include <rpcerr.h>
|
|
#include <wfext.h>
|
|
#include "homedrv.h"
|
|
#include "home.h" // header file generated by MIDL compiler
|
|
#include "..\homedir.h" // Server/client error codes
|
|
|
|
//
|
|
// Global variables
|
|
//
|
|
|
|
HANDLE ghDllInst; // DLL's instance handle
|
|
HMENU ghMenu; // Extension's menu handle
|
|
WORD gwMenuDelta; // Delta for extension's menu items
|
|
char gOldAddress[STRINGSIZE]; // Server network address
|
|
BOOL gRefreshNecessary; // Tells if FM needs to refresh windows
|
|
|
|
//
|
|
// Function prototypes
|
|
//
|
|
|
|
HMENU FAR PASCAL
|
|
FMExtensionProc (
|
|
HWND hwndExtension,
|
|
WORD wMesssage,
|
|
LONG lParam
|
|
);
|
|
BOOL FAR PASCAL
|
|
AboutDlgProc (
|
|
HWND hDlg,
|
|
unsigned uMessage,
|
|
WORD wParam,
|
|
LONG lParam
|
|
);
|
|
BOOL FAR PASCAL
|
|
MenuADG(
|
|
HWND hDlg,
|
|
unsigned message,
|
|
WORD wParam,
|
|
LONG lParam
|
|
);
|
|
void
|
|
Connect(
|
|
char * drive,
|
|
char *dir
|
|
);
|
|
void
|
|
CheckWinStatus(
|
|
UINT status
|
|
);
|
|
void
|
|
CheckRpcStatus(
|
|
char *ProcName,
|
|
RPC_STATUS status
|
|
);
|
|
void
|
|
CheckMyStatus(
|
|
char *ProcName,
|
|
MY_STATUS status
|
|
);
|
|
void
|
|
CreateBinding(
|
|
char *Address
|
|
);
|
|
void
|
|
DestroyBinding(
|
|
void
|
|
);
|
|
|
|
|
|
//***************************************************************************
|
|
//
|
|
// LibMain()
|
|
//
|
|
// Purpose:
|
|
//
|
|
// LibMain is called by LibEntry. LibEntry is called by Windows
|
|
// when the DLL is loaded. The LibEntry routine is provided
|
|
// in the LIBENTRY.OBJ in the SDK Link Libraries disk. (The
|
|
// source LIBENTRY.ASM is also provided.)
|
|
//
|
|
// LibEntry initializes the DLL's heap if a HEAPSIZE value is
|
|
// specified in the DLL's DEF file. After this, LibEntry calls
|
|
// LibMain. The LibMain function below satisfies that call.
|
|
//
|
|
// The LibMain function should perform additional initialization
|
|
// tasks required by the DLL. LibMain should return a value of
|
|
// TRUE if the initialization is successful.
|
|
//
|
|
//
|
|
// Parameters:
|
|
//
|
|
// IN:
|
|
// hLibInst - DLLs instance handle
|
|
// wDataSeg - Data segment
|
|
// cbHeapSize - Size of the DLL's heap
|
|
// lpszCmdLine - Command line
|
|
//
|
|
// OUT:
|
|
// N/A
|
|
//
|
|
// Return Value:
|
|
//
|
|
// TRUE if the initialization is successful; FALSE otherwise.
|
|
//
|
|
//***************************************************************************
|
|
|
|
int FAR PASCAL
|
|
LibMain (
|
|
HANDLE hLibInst,
|
|
WORD wDataSeg,
|
|
WORD cbHeapSize,
|
|
LPSTR lpszCmdLine
|
|
)
|
|
{
|
|
char server[STRINGSIZE];
|
|
|
|
if(GetPrivateProfileString("HomeDrive", // Section of winfile.ini
|
|
"Server", // Variable
|
|
"", // Default
|
|
server, // Where to put it
|
|
STRINGSIZE,
|
|
"winfile.ini"))
|
|
{
|
|
CreateBinding(server);
|
|
strcpy(gOldAddress,server); // save the address
|
|
}
|
|
ghDllInst = hLibInst;
|
|
return (TRUE);
|
|
} // LibMain()
|
|
|
|
//***************************************************************************
|
|
//
|
|
// WEP()
|
|
//
|
|
// Purpose:
|
|
//
|
|
// Performs cleanup tasks when the .DLL is unloaded; in this case,
|
|
// it destroys the binding to the RPC HomeDrive server. The WEP()
|
|
// is called automatically by Windows when the DLL is unloaded.
|
|
//
|
|
// Make sure that the WEP() is @1 RESIDENTNAME in the EXPORTS
|
|
// section of the .DEF file. This ensures that the WEP() can
|
|
// be called as quickly as possible. Incidently, this is why
|
|
// the WEP() is called the WEP() instead of WindowsExitProcedure().
|
|
// It takes up the minimum amount of space and is quickly located.
|
|
//
|
|
//
|
|
// Parameters:
|
|
//
|
|
// IN:
|
|
// bSystemExit - Type of exit
|
|
//
|
|
// OUT:
|
|
// N/A
|
|
//
|
|
// Return Value:
|
|
//
|
|
// TRUE.
|
|
//
|
|
//***************************************************************************
|
|
|
|
int FAR PASCAL
|
|
WEP(
|
|
int bSystemExit
|
|
)
|
|
{
|
|
DestroyBinding();
|
|
return (TRUE);
|
|
} // WEP()
|
|
|
|
|
|
//***************************************************************************
|
|
//
|
|
// FMExtensionProc()
|
|
//
|
|
// Purpose:
|
|
//
|
|
// This is an application-defined callback function. It processes menu
|
|
// commands and messages sent to HOMEDRV.DLL.
|
|
//
|
|
//
|
|
// Parameters:
|
|
//
|
|
// IN:
|
|
// hwndExtension - Identifies the File Manager window
|
|
// wMessage - Message sent to extension DLL
|
|
// lParam - Message information
|
|
//
|
|
// OUT:
|
|
// N/A
|
|
//
|
|
// Return Value:
|
|
//
|
|
// When the wMessage is FMEVENT_INITMENU, handle to extension's menu
|
|
// should be returned; otherwise a NULL value.
|
|
//
|
|
//***************************************************************************
|
|
|
|
HMENU FAR PASCAL
|
|
FMExtensionProc (
|
|
HWND hwndExtension,
|
|
WORD wMessage,
|
|
LONG lParam
|
|
)
|
|
{
|
|
LPFMS_LOAD lpLoad;
|
|
FARPROC lpDialogProc;
|
|
FARPROC lpProc; // pointer to the chosen function
|
|
|
|
switch (wMessage)
|
|
{
|
|
|
|
// ****************** File Manager Events
|
|
|
|
case FMEVENT_LOAD:
|
|
lpLoad = (LPFMS_LOAD) lParam;
|
|
|
|
// Assign the menu handle from the DLL's resource
|
|
|
|
ghMenu = LoadMenu (ghDllInst, "ExtensionMenu");
|
|
lpLoad->hMenu = ghMenu;
|
|
|
|
// This is the delta we are being assigned.
|
|
|
|
gwMenuDelta = lpLoad->wMenuDelta;
|
|
|
|
// Size of the load structure
|
|
|
|
lpLoad->dwSize = sizeof (FMS_LOAD);
|
|
|
|
// Assign the popup menu name for this extension
|
|
|
|
lstrcpy (lpLoad->szMenuName, "Ho&meDrive");
|
|
|
|
// Return that handle
|
|
|
|
return (ghMenu);
|
|
|
|
|
|
// ****************** Extension menu commands
|
|
|
|
case IDM_CONNECT:
|
|
gRefreshNecessary=FALSE;
|
|
lpProc = MakeProcInstance(MenuADG, ghDllInst);
|
|
DialogBox(ghDllInst, // current instance
|
|
"CONNECTBOX", // resource to use
|
|
hwndExtension, // parent handle
|
|
lpProc); // About() instance address
|
|
if (gRefreshNecessary)
|
|
{
|
|
SendMessage(hwndExtension,
|
|
FM_REFRESH_WINDOWS, // To bring the drive up
|
|
1, // Non-zero refreshes all windows
|
|
0L);
|
|
}
|
|
FreeProcInstance(AboutDlgProc);
|
|
break;
|
|
|
|
case IDM_ABOUTEXT:
|
|
lpDialogProc = MakeProcInstance(AboutDlgProc, ghDllInst);
|
|
DialogBox (ghDllInst,
|
|
"ABOUTBOX",
|
|
hwndExtension,
|
|
lpDialogProc);
|
|
FreeProcInstance(AboutDlgProc);
|
|
break;
|
|
}
|
|
|
|
return (NULL);
|
|
|
|
} // FMExtensionProc()
|
|
|
|
|
|
//***************************************************************************
|
|
//
|
|
// AboutDlgProc()
|
|
//
|
|
// Purpose:
|
|
//
|
|
// Procedure to handle About dialog messages. This dialog displays
|
|
// copyright and help information.
|
|
//
|
|
//
|
|
// Parameters:
|
|
//
|
|
// IN:
|
|
// hDlg - Dialog window handle
|
|
// uMessage - Dialog message
|
|
// wParam - Message information
|
|
// lParam - Additional message information
|
|
//
|
|
// OUT:
|
|
// N/A
|
|
//
|
|
// Return Value:
|
|
//
|
|
// Appropriate value for the dialog message.
|
|
//
|
|
//***************************************************************************
|
|
|
|
BOOL FAR PASCAL
|
|
AboutDlgProc(
|
|
HWND hDlg,
|
|
unsigned uMessage,
|
|
WORD wParam,
|
|
LONG lParam
|
|
)
|
|
{
|
|
#define ICONLEFTCOORD 8
|
|
#define ICONTOPCOORD 8
|
|
#define ICONRIGHTCOORD 40
|
|
#define ICONBOTTOMCOORD 40
|
|
|
|
#define ICONXLOC 9
|
|
#define ICONYLOC 8
|
|
|
|
HDC hdc;
|
|
int i;
|
|
DWORD temp;
|
|
int x;
|
|
int y;
|
|
static HWND hIcon[16];
|
|
volatile int j;
|
|
static BOOL FirstTime=TRUE;
|
|
static BOOL CookieOn=FALSE;
|
|
|
|
switch (uMessage)
|
|
{
|
|
case WM_INITDIALOG:
|
|
for(i=0;i<16;i++)
|
|
hIcon[i]=LoadIcon(ghDllInst,MAKEINTRESOURCE(ANIM1+i));
|
|
return (TRUE);
|
|
|
|
case WM_COMMAND:
|
|
switch (wParam)
|
|
{
|
|
case IDOK:
|
|
case IDCANCEL:
|
|
for(i=0;i<16;i++)
|
|
DestroyIcon(hIcon[i]);
|
|
EndDialog (hDlg, TRUE);
|
|
return (TRUE);
|
|
|
|
default:
|
|
break;
|
|
} // switch (wParam)
|
|
|
|
case WM_LBUTTONUP:
|
|
case WM_RBUTTONUP:
|
|
if((CookieOn != (uMessage==WM_LBUTTONUP)) && (wParam & MK_CONTROL))
|
|
{
|
|
hdc=GetDC(hDlg);
|
|
temp=GetCurrentPosition(hdc);
|
|
x=LOWORD(lParam)-LOWORD(temp);
|
|
y=HIWORD(lParam)-HIWORD(temp);
|
|
if((x>ICONLEFTCOORD)&&(x<ICONRIGHTCOORD)&&
|
|
(y>ICONTOPCOORD)&&(y<ICONBOTTOMCOORD))
|
|
{
|
|
if(uMessage==WM_LBUTTONUP)
|
|
{
|
|
i=1;
|
|
}
|
|
else
|
|
{
|
|
i=15;
|
|
}
|
|
for(;(i<16) && (i>0);)
|
|
{
|
|
DrawIcon(hdc,ICONXLOC,ICONYLOC,hIcon[i]);
|
|
if(!FirstTime)
|
|
{
|
|
for(j=0;j<30000;j++);
|
|
}
|
|
if(uMessage==WM_LBUTTONUP)
|
|
{
|
|
i++;
|
|
}
|
|
else
|
|
{
|
|
i--;
|
|
}
|
|
}
|
|
DrawIcon(hdc,ICONXLOC,ICONYLOC,hIcon[0]);
|
|
FirstTime=FALSE;
|
|
if(uMessage==WM_LBUTTONUP)
|
|
{
|
|
ShowWindow(GetDlgItem(hDlg,ID_OPAQUERECT),SW_SHOWNORMAL);
|
|
ShowWindow(GetDlgItem(hDlg,ID_CREDITS),SW_SHOWNORMAL);
|
|
CookieOn=TRUE;
|
|
}
|
|
else
|
|
{
|
|
ShowWindow(GetDlgItem(hDlg,ID_OPAQUERECT),SW_HIDE);
|
|
ShowWindow(GetDlgItem(hDlg,ID_CREDITS),SW_HIDE);
|
|
CookieOn=FALSE;
|
|
}
|
|
ReleaseDC(hDlg,hdc);
|
|
return(TRUE);
|
|
}
|
|
else
|
|
{
|
|
ReleaseDC(hDlg,hdc);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case WM_DESTROY:
|
|
CookieOn=FALSE;
|
|
|
|
} // switch (message)
|
|
|
|
return (FALSE);
|
|
} // AboutDlgProc
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
FUNCTION: MenuADG(HWND, unsigned, WORD, LONG)
|
|
|
|
PURPOSE: Processes messages for the "Connect" dialog box.
|
|
|
|
MESSAGES:
|
|
|
|
WM_INITDIALOG - initialize dialog box
|
|
WM_COMMAND - Input received
|
|
|
|
COMMENTS:
|
|
|
|
****************************************************************************/
|
|
|
|
BOOL FAR PASCAL
|
|
MenuADG(
|
|
HWND hDlg, // window handle of the dialog box
|
|
unsigned message, // type of message
|
|
WORD wParam, // message-specific information
|
|
LONG lParam
|
|
)
|
|
{
|
|
char name[STRINGSIZE];
|
|
char dir[STRINGSIZE];
|
|
char server[STRINGSIZE];
|
|
char drive[3]="E:"; // It would be a shame to change 3 to STRINGSIZE.
|
|
HWND hWndListBox;
|
|
MY_STATUS TempStat;
|
|
|
|
switch (message) {
|
|
case WM_INITDIALOG: // message: initialize dialog box
|
|
// Initialize Drive list box
|
|
hWndListBox = GetDlgItem(hDlg, IDDRIVE);
|
|
while(drive[0]<='Z')
|
|
{
|
|
SendMessage(hWndListBox,
|
|
LB_ADDSTRING,
|
|
0,
|
|
(LONG) ((char _far *) drive));
|
|
(drive[0])++;
|
|
}
|
|
|
|
// Get defaults from stored data in winfile.ini
|
|
if(GetPrivateProfileString("HomeDrive", // Section of winfile.ini
|
|
"Name", // Variable
|
|
"", // Default
|
|
name, // Where to put it
|
|
STRINGSIZE,
|
|
"winfile.ini"))
|
|
{
|
|
SetDlgItemText(hDlg, IDNAME, name);
|
|
}
|
|
SetDlgItemText(hDlg, IDSERVER, gOldAddress);
|
|
if(GetPrivateProfileString("HomeDrive", // Section of winfile.ini
|
|
"Drive", // Variable
|
|
"", // Default
|
|
drive, // Where to put it
|
|
3,
|
|
"winfile.ini"))
|
|
{
|
|
SendMessage(hWndListBox,
|
|
LB_SELECTSTRING,
|
|
(UINT) -1,
|
|
(LONG) ((char _far *) drive));
|
|
}
|
|
return (TRUE);
|
|
|
|
case WM_COMMAND: // message: received a command
|
|
switch (wParam)
|
|
{
|
|
case IDOK: // "OK" box selected?
|
|
hWndListBox = GetDlgItem(hDlg, IDDRIVE);
|
|
GetDlgItemText(hDlg,IDNAME,name,STRINGSIZE);
|
|
GetDlgItemText(hDlg,IDSERVER,server,STRINGSIZE);
|
|
if (strcmp(gOldAddress,server)) // server has changed
|
|
{
|
|
DestroyBinding();
|
|
CreateBinding(server);
|
|
strcpy(gOldAddress,server);
|
|
}
|
|
SendMessage(hWndListBox,
|
|
LB_GETTEXT,
|
|
(WORD) SendMessage(hWndListBox,
|
|
LB_GETCURSEL,
|
|
0,
|
|
0L),
|
|
(LONG) ((char _far *) drive));
|
|
|
|
// Save defaults
|
|
WritePrivateProfileString("HomeDrive","Name",name,
|
|
"winfile.ini");
|
|
WritePrivateProfileString("HomeDrive","Server",server,
|
|
"winfile.ini");
|
|
WritePrivateProfileString("HomeDrive","Drive",drive,
|
|
"winfile.ini");
|
|
RpcTryExcept
|
|
{
|
|
CheckMyStatus(
|
|
"RPC Get call",
|
|
TempStat = RpcHomesvrGet(name,dir)
|
|
);
|
|
if (!TempStat)
|
|
{
|
|
Connect(drive,dir);
|
|
}
|
|
}
|
|
RpcExcept(1)
|
|
{
|
|
CheckRpcStatus("Runtime library reported an exception",
|
|
RpcExceptionCode()
|
|
);
|
|
}
|
|
RpcEndExcept
|
|
if (!TempStat)
|
|
{
|
|
EndDialog(hDlg, TRUE);
|
|
}
|
|
return (TRUE);
|
|
|
|
case IDCANCEL:
|
|
EndDialog(hDlg, TRUE);
|
|
return (TRUE);
|
|
|
|
case IDDRIVE:
|
|
// If the user double clicks the list box, treat it as OK.
|
|
if (HIWORD(lParam)==LBN_DBLCLK)
|
|
{
|
|
SendMessage(hDlg,WM_COMMAND,IDOK,0L);
|
|
}
|
|
|
|
}
|
|
break;
|
|
}
|
|
return (FALSE); // Didn't process a message
|
|
}
|
|
|
|
void
|
|
Connect(
|
|
char *Drive,
|
|
char *Dir
|
|
)
|
|
{
|
|
// I assume that the share is valid. The syntax is checked by the
|
|
// HomeDrive administrative application when it's entered into the
|
|
// database, so it's a good bet.
|
|
char Share[STRINGSIZE];
|
|
char Subdir[STRINGSIZE];
|
|
char CurrConnect[STRINGSIZE];
|
|
UINT BuffSize=STRINGSIZE;
|
|
UINT status;
|
|
int i=0;
|
|
int j=0;
|
|
int k;
|
|
|
|
// Parse the share information.
|
|
for(k=1;k<=4;k++)
|
|
{
|
|
while(Dir[i]!='\\' && Dir[i]!='\0')
|
|
{
|
|
Share[i]=Dir[i];
|
|
i++;
|
|
}
|
|
Share[i]=Dir[i];
|
|
i++;
|
|
}
|
|
Share[--i]='\0';
|
|
while(Dir[i]!='\0')
|
|
{
|
|
Subdir[j]=Dir[i];
|
|
i++;
|
|
j++;
|
|
}
|
|
Subdir[j]='\0';
|
|
|
|
switch(status=WNetGetConnection(Drive,CurrConnect,&BuffSize))
|
|
{
|
|
case WN_NOT_CONNECTED:
|
|
gRefreshNecessary=TRUE;
|
|
status=WNetAddConnection(Share,"",Drive);
|
|
CheckWinStatus(status);
|
|
// If the File Manager had more hooks, I'd actually do this.
|
|
//if (status==WN_SUCCESS)
|
|
// {
|
|
// change directory
|
|
// change drive
|
|
// }
|
|
break;
|
|
|
|
case WN_CONNECTION_CLOSED:
|
|
gRefreshNecessary=TRUE;
|
|
status=WNetCancelConnection(Drive,TRUE); // TRUE _forces_ close
|
|
CheckWinStatus(status);
|
|
if (status==WN_SUCCESS)
|
|
{
|
|
status=WNetAddConnection(Share,"",Drive);
|
|
CheckWinStatus(status);
|
|
//if (status==WN_SUCCESS)
|
|
// {
|
|
// change directory
|
|
// change drive
|
|
// }
|
|
}
|
|
break;
|
|
|
|
case WN_SUCCESS:
|
|
if(strcmp(_strlwr(CurrConnect),Share)!=0) // Share is lowercase
|
|
{
|
|
gRefreshNecessary=TRUE;
|
|
status=WNetCancelConnection(Drive,TRUE); // TRUE _forces_ close
|
|
CheckWinStatus(status);
|
|
if (status==WN_SUCCESS)
|
|
{
|
|
status=WNetAddConnection(Share,"",Drive);
|
|
CheckWinStatus(status);
|
|
//if (status==WN_SUCCESS)
|
|
// {
|
|
// change directory
|
|
// change drive
|
|
// }
|
|
}
|
|
}
|
|
//else // already connected
|
|
// {
|
|
// change directory
|
|
// change drive
|
|
// }
|
|
break;
|
|
|
|
default:
|
|
CheckWinStatus(status);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void
|
|
CheckWinStatus(
|
|
UINT status
|
|
)
|
|
{
|
|
char temp[60];
|
|
|
|
switch (status)
|
|
{
|
|
case WN_SUCCESS:
|
|
break;
|
|
case WN_NOT_SUPPORTED:
|
|
MessageBox(HWND_DESKTOP,
|
|
"That function is not supported by your network.",
|
|
"Error",
|
|
MB_OK);
|
|
break;
|
|
case WN_OUT_OF_MEMORY:
|
|
MessageBox(HWND_DESKTOP,
|
|
"Out of memory.",
|
|
"Error",
|
|
MB_OK);
|
|
break;
|
|
case WN_NET_ERROR:
|
|
MessageBox(HWND_DESKTOP,
|
|
"An error occured on the network.",
|
|
"Error",
|
|
MB_OK);
|
|
break;
|
|
case WN_BAD_NETNAME:
|
|
MessageBox(HWND_DESKTOP,
|
|
"Your network share could not be reached.",
|
|
"Error",
|
|
MB_OK);
|
|
break;
|
|
case WN_BAD_PASSWORD:
|
|
case WN_ACCESS_DENIED:
|
|
MessageBox(HWND_DESKTOP,
|
|
"Access denied. Check your password, or see your system administrator.",
|
|
"Error",
|
|
MB_OK);
|
|
break;
|
|
case WN_BAD_VALUE:
|
|
case WN_BAD_LOCALNAME:
|
|
MessageBox(HWND_DESKTOP,
|
|
"Invalid drive specification.",
|
|
"Error",
|
|
MB_OK);
|
|
break;
|
|
case WN_OPEN_FILES:
|
|
MessageBox(HWND_DESKTOP,
|
|
"Could not delete previous connection. Try closing files open on that drive.",
|
|
"Error",
|
|
MB_OK);
|
|
break;
|
|
case WN_BAD_POINTER:
|
|
case WN_MORE_DATA:
|
|
default:
|
|
wsprintf(temp,
|
|
"Internal error %u; contact your system administrator.",
|
|
status);
|
|
|
|
MessageBox(HWND_DESKTOP,
|
|
temp,
|
|
"Error",
|
|
MB_OK);
|
|
}
|
|
}
|
|
|
|
void
|
|
CheckRpcStatus(
|
|
char *ProcName,
|
|
MY_STATUS status
|
|
)
|
|
{
|
|
char buffer[10];
|
|
char temp[100] = "RPC Exception in ";
|
|
|
|
switch (status)
|
|
{
|
|
case RPC_S_INVALID_STRING_BINDING:
|
|
case RPC_S_SERVER_UNAVAILABLE:
|
|
case RPC_S_CALL_FAILED_DNE:
|
|
case RPC_S_ACCESS_DENIED:
|
|
MessageBox(HWND_DESKTOP,
|
|
"Check that the HomeDrive server is running on an accessible server.",
|
|
strcat(
|
|
temp,
|
|
ProcName
|
|
),
|
|
MB_OK);
|
|
break;
|
|
|
|
case RPC_S_OK:
|
|
break;
|
|
|
|
default:
|
|
MessageBox(HWND_DESKTOP,
|
|
_itoa(status,buffer,10),
|
|
strcat(
|
|
temp,
|
|
ProcName
|
|
),
|
|
MB_OK);
|
|
}
|
|
}
|
|
|
|
void
|
|
CheckMyStatus(
|
|
char *ProcName,
|
|
MY_STATUS status
|
|
)
|
|
{
|
|
char buffer[10];
|
|
|
|
switch (status) {
|
|
case HOMEDIR_S_OK:
|
|
break;
|
|
|
|
case HOMEDIR_S_ENTRY_ALREADY_EXISTS:
|
|
MessageBox(HWND_DESKTOP,
|
|
"That name is already in the database.",
|
|
"Error",
|
|
MB_OK);
|
|
break;
|
|
|
|
case HOMEDIR_S_ENTRY_NOT_FOUND:
|
|
MessageBox(HWND_DESKTOP,
|
|
"That name is not in the database.",
|
|
"Error",
|
|
MB_OK);
|
|
break;
|
|
|
|
default: // This should never happen
|
|
MessageBox(HWND_DESKTOP,
|
|
_itoa(
|
|
status,
|
|
buffer,
|
|
10
|
|
),
|
|
"Fatal Error",
|
|
MB_OK);
|
|
}
|
|
}
|
|
|
|
// ====================================================================
|
|
// MIDL allocate and free
|
|
// ====================================================================
|
|
|
|
|
|
void *
|
|
MIDL_user_allocate(
|
|
size_t len
|
|
)
|
|
{
|
|
return(malloc(len));
|
|
}
|
|
|
|
void
|
|
MIDL_user_free(
|
|
void * ptr
|
|
)
|
|
{
|
|
free(ptr);
|
|
}
|
|
|
|
void
|
|
CreateBinding(
|
|
char *pszNetworkAddress
|
|
)
|
|
{
|
|
char * pszUuid = "12345678-1234-1234-1234-123456789ABC";
|
|
char * pszProtocolSequence = "ncacn_np";
|
|
char * pszEndpoint = "\\pipe\\home";
|
|
char * pszOptions = NULL;
|
|
char * pszStringBinding = NULL;
|
|
|
|
// FUTURE ENHANCEMENT: use the locator to find the server.
|
|
/*
|
|
RPC_NS_HANDLE ImportContext;
|
|
|
|
CheckRpcStatus("RpcNsBindingImportBegin",
|
|
RpcNsBindingImportBegin(
|
|
RPC_C_NS_SYNTAX_DEFAULT,
|
|
"/.:/Home",
|
|
home_ClientIfHandle,
|
|
NULL,
|
|
&ImportContext
|
|
)
|
|
);
|
|
|
|
CheckRpcStatus("RpcNsBindingImportNext",
|
|
RpcNsBindingImportNext(
|
|
ImportContext,
|
|
&home_BindingHandle
|
|
)
|
|
);
|
|
|
|
CheckRpcStatus("RpcNsBindingImportDone",
|
|
RpcNsBindingImportDone(&ImportContext)
|
|
);
|
|
*/
|
|
|
|
//
|
|
CheckRpcStatus("RpcStringBindingCompose",
|
|
RpcStringBindingCompose(
|
|
(unsigned char *) pszUuid,
|
|
(unsigned char *) pszProtocolSequence,
|
|
(unsigned char *) pszNetworkAddress,
|
|
(unsigned char *) pszEndpoint,
|
|
(unsigned char *) pszOptions,
|
|
(unsigned char * *) &pszStringBinding
|
|
)
|
|
);
|
|
|
|
|
|
// Set the binding handle that will be used to bind to the server.
|
|
|
|
CheckRpcStatus("RpcBindingFromStringBinding",
|
|
RpcBindingFromStringBinding(
|
|
(unsigned char *) pszStringBinding,
|
|
&home_BindingHandle
|
|
)
|
|
);
|
|
|
|
CheckRpcStatus("RpcStringFree",
|
|
RpcStringFree((unsigned char * *) &pszStringBinding)
|
|
);
|
|
//
|
|
}
|
|
|
|
void
|
|
DestroyBinding(
|
|
void
|
|
)
|
|
{
|
|
CheckRpcStatus("RpcBindingFree",
|
|
RpcBindingFree(&home_BindingHandle));
|
|
}
|