//-------------------------------------------------------------------------- // // Copyright (C) 1999, Microsoft Corporation // // File: infile.cxx // //-------------------------------------------------------------------------- #define UNICODE 1 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "struct.hxx" #include "ftsup.hxx" #include "stdsup.hxx" #include "rootsup.hxx" #include "misc.hxx" #include "messages.h" #include "fileio.hxx" // // These are extensions for perf/scalability // Undoc'd for now, only apply when scripting // FMAKEARG(AddRoot); FMAKEARG(RemRoot); FMAKEARG(Share); FMAKEARG(Server); FMAKEARG(Link); FMAKEARG(Site); FMAKEARG(ShortPrefix); FMAKEARG(Add); FMAKEARG(State); FMAKEARG(Type); FMAKEARG(Guid); FMAKEARG(Timeout); FMAKEARG(Comment) FMAKEARG(Load); FMAKEARG(Save); FMAKEARG(DcName); FSWITCH(Map); FSWITCH(UnMap); FSWITCH(Mod); LPWSTR pgDfsName = NULL; LPWSTR pgDcName = NULL; LPWSTR pgLink = NULL; LPWSTR pgSite = NULL; LPWSTR pgShortLink = NULL; LPWSTR pgTimeout = NULL; LPWSTR pgState = NULL; LPWSTR pgType = NULL; LPWSTR pgGuid = NULL; LPWSTR pgComment = NULL; LPWSTR pgAddArg = NULL; LPWSTR pgDomDfsName = NULL; LPWSTR pgServerName = NULL; LPWSTR pgShareName = NULL; #define UNICODE_COMMENT_CHAR L'/' // // Protos // DWORD CmdLoad( PDFS_VOLUME_LIST pDfsVolList, LPWSTR pDfsName, LPWSTR pDcName); DWORD CmdSave( PDFS_VOLUME_LIST pDfsVolList, LPWSTR pDfsName, LPWSTR pDcName); DWORD CmdLinkMap( PDFS_VOLUME_LIST pDfsVolList, LPWSTR pLink, LPWSTR pShortLink, LPWSTR pComment, LPWSTR pTimeout, LPWSTR pState, LPWSTR pType, LPWSTR pGUID, ULONG LineNum); DWORD CmdLink( PDFS_VOLUME_LIST pDfsVolList, LPWSTR pLink, ULONG LineNum); DWORD CmdLinkMod( PDFS_VOLUME_LIST pDfsVolList, LPWSTR pLink, LPWSTR pgShortLink, LPWSTR pComment, LPWSTR pTimeout, LPWSTR pState, LPWSTR pType, LPWSTR pGUID, ULONG LineNum); DWORD CmdLinkUnmap( PDFS_VOLUME_LIST pDfsVolList, LPWSTR pLink, ULONG LineNum); DWORD CmdAdd( PDFS_VOLUME_LIST pDfsVolList, LPWSTR pLink, LPWSTR pAltName, LPWSTR pState, LPWSTR Type, ULONG LineNum); BOOLEAN CmdProcessInfileArg( LPWSTR Arg); DWORD DfspBreakName( LPWSTR pPath, LPWSTR *ppServerName, LPWSTR *ppShareName); DWORD DfspDomLoad( PDFS_VOLUME_LIST pDfsVolList, LPWSTR pDomName, LPWSTR pDfsName, LPWSTR pDcName); DWORD DfspStdLoad( PDFS_VOLUME_LIST pDfsVolList, LPWSTR pServerName, LPWSTR pShareName, LPWSTR pDcName); DWORD DfspDomSave( PDFS_VOLUME_LIST pDfsVolList, LPWSTR pDomName, LPWSTR pDfsName, LPWSTR pDcName); DWORD DfspStdSave( PDFS_VOLUME_LIST pDfsVolList, LPWSTR pServerName, LPWSTR pShareName); DWORD CmdSite( PDFS_VOLUME_LIST pDfsVolList, LPWSTR pServer, ULONG LineNum); DWORD CmdSiteMap( PDFS_VOLUME_LIST pDfsVolList, LPWSTR pServer, ULONG LineNum); DWORD CmdAddSiteToServer( PDFS_VOLUME_LIST pDfsVolList, LPWSTR pServer, LPWSTR pSite, ULONG LineNum); DWORD CmdSiteUnmap( PDFS_VOLUME_LIST pDfsVolList, LPWSTR pServer, ULONG LineNum); VOID DfspExportFile( HANDLE pHandle, PDFS_VOLUME_LIST pDfsVolList); #define INIT_LINK_COUNT 8 #define INIT_ALT_COUNT 2 // // The one that gets it all going - use a file // DWORD CmdImport( LPWSTR pInfile) { DWORD dwErr = ERROR_SUCCESS; DFS_VOLUME_LIST DfsVolList = { 0 }; PDFS_VOLUME_LIST pDfsVolList = &DfsVolList; LONG i; FILE *fp; WCHAR InBuf[1026]; LPWSTR *argvw; PWCHAR wCp; ULONG LineNum = 1; int argcw; int argx; if (fSwDebug == TRUE) MyPrintf(L"CmdImport(%ws)\r\n", pInfile); fp = _wfopen(pInfile, L"r"); if (fp == NULL) { if (fSwDebug == TRUE) MyPrintf(L"Can not open %ws for read.\r\n", pInfile); dwErr = ERROR_FILE_NOT_FOUND; goto Cleanup; } while (fgetws(InBuf, sizeof(InBuf)/sizeof(WCHAR), fp) != NULL) { // Remove trailing CR/LF for (wCp = InBuf; *wCp != L'\0'; wCp++) { if (*wCp == L'\r' || *wCp == L'\n') *wCp = L'\0'; } // Strip off comments (indicated by a // ) for (wCp = InBuf; *wCp != L'\0'; wCp++) if (wCp > InBuf && *wCp == UNICODE_COMMENT_CHAR && *(wCp-1) == UNICODE_COMMENT_CHAR) { *(wCp-1) = L'\0'; break; } // Remove trailing spaces and tabs while (wCp != InBuf && (*wCp == L' ' || *wCp == L'\t')) *wCp-- = L'\0'; // Remove leading spaces and tabs for (wCp = InBuf; *wCp != L'\0' && (*wCp == L' ' || *wCp == L'\t'); wCp++) NOTHING; if (fSwDebug == TRUE) MyPrintf(L"%d:[%ws]\r\n", LineNum, wCp); if (wcslen(wCp) == 0) { LineNum++; continue; } argvw = CommandLineToArgvW(wCp, &argcw); fArgAddRoot = FALSE; fArgRemRoot = FALSE; fArgLoad = FALSE; fArgLink = FALSE; fArgSite = FALSE; fArgAdd = FALSE; fSwMap = FALSE; fSwUnMap = FALSE; fSwMod = FALSE; pgShortLink = NULL; pgTimeout = NULL; pgState = NULL; pgType = NULL; pgGuid = NULL; pgComment = NULL; pgAddArg = NULL; pgDomDfsName = NULL; pgServerName = NULL; for (argx = 0; argx < argcw; argx++) { if (fSwDebug == TRUE) MyPrintf(L"%d: [%ws]\r\n", argx, argvw[argx]); if (CmdProcessInfileArg(argvw[argx]) != TRUE) { dwErr = ERROR_INVALID_PARAMETER; MyPrintf(L"Unrecognized parameter in line %d\r\n", LineNum); } } if (fSwDebug == TRUE) { MyPrintf(L"DfsName=%ws\r\n", pgDfsName); MyPrintf(L"DcName=%ws\r\n", pgDcName); MyPrintf(L"Link=%ws\r\n", pgLink); MyPrintf(L"ShortLink=%ws\r\n", pgShortLink); MyPrintf(L"Site=%ws\r\n", pgSite); MyPrintf(L"Timeout=%ws\r\n", pgTimeout); MyPrintf(L"State=%ws\r\n", pgState); MyPrintf(L"Type=%ws\r\n", pgType); MyPrintf(L"Guid=%ws\r\n", pgGuid); MyPrintf(L"Comment=%ws\r\n", pgComment); MyPrintf(L"AddArg=%ws\r\n", pgAddArg); } // // Do the work // if (fArgLoad == TRUE) { dwErr = CmdLoad( pDfsVolList, pgDfsName, pgDcName); } else if (fArgLink == TRUE) { if (fSwMap == TRUE) { dwErr = CmdLinkMap( pDfsVolList, pgLink, pgShortLink, pgComment, pgTimeout, pgState, pgType, pgGuid, LineNum); } else if (fSwMod == TRUE) { dwErr = CmdLinkMod( pDfsVolList, pgLink, pgShortLink, pgComment, pgTimeout, pgState, pgType, pgGuid, LineNum); } else if (fSwUnMap == TRUE) { dwErr = CmdLinkUnmap( pDfsVolList, pgLink, LineNum); } else { dwErr = CmdLink( pDfsVolList, pgLink, LineNum); } } else if (fArgSite == TRUE) { if (fSwMap == TRUE) { dwErr = CmdSiteMap( pDfsVolList, pgSite, LineNum); } else if (fSwUnMap == TRUE) { dwErr = CmdSiteUnmap( pDfsVolList, pgSite, LineNum); } else { dwErr = CmdSite( pDfsVolList, pgSite, LineNum); } } else if (fArgAdd == TRUE) { if (pgLink != NULL) { dwErr = CmdAdd( pDfsVolList, pgLink, pgAddArg, pgState, pgType, LineNum); } else if (pgSite != NULL) { dwErr = CmdAddSiteToServer( pDfsVolList, pgSite, pgAddArg, LineNum); } } else if (fArgSave == TRUE) { dwErr = CmdSave( pDfsVolList, pgDfsName, pgDcName); } else if (fArgAddRoot == TRUE) { dwErr = CmdAddRoot( pgDomDfsName, pgServerName, pgShareName, pgComment); } else if (fArgRemRoot == TRUE) { dwErr = CmdRemRoot( pgDomDfsName, pgServerName, pgShareName); } else { MyPrintf(L"Missing command in line %d\r\n", LineNum); } if(dwErr != ERROR_SUCCESS) { MyPrintf(L"Import: Error %d processing line %d.\r\n", dwErr, LineNum); goto Cleanup; } LineNum++; } Cleanup: // DfsViewVolList(pDfsVolList, 1); if (fSwDebug == TRUE) DfsDumpVolList(pDfsVolList); // // Free our vol list // DfsFreeVolList(pDfsVolList); if (fSwDebug == TRUE) MyPrintf(L"CmdImport exit %d\r\n", dwErr); return dwErr; } DWORD CmdLoad( PDFS_VOLUME_LIST pDfsVolList, LPWSTR pDfsName, LPWSTR pDcName) { DWORD dwErr = ERROR_SUCCESS; LPWSTR pServerName = NULL; LPWSTR pShareName = NULL; BOOLEAN IsDomainName = FALSE; if (fSwDebug == TRUE) MyPrintf(L"CmdLoad(%ws,%ws)\r\n", pDfsName, pDcName); if (pDfsName == NULL) { dwErr = ERROR_INVALID_PARAMETER; goto Cleanup; } dwErr = DfspParseName( pDfsName, &pServerName, &pShareName); if (dwErr != ERROR_SUCCESS) goto Cleanup; dwErr = DfspIsDomainName( pServerName, pDcName, &IsDomainName); if (dwErr != ERROR_SUCCESS) goto Cleanup; if (IsDomainName == TRUE) { dwErr = DfspDomLoad( pDfsVolList, pServerName, pShareName, pDcName); } else { dwErr = DfspStdLoad( pDfsVolList, pServerName, pShareName, pDcName); } if (dwErr != ERROR_SUCCESS) goto Cleanup; // // The link list may not be sorted - do so now. // DfspSortVolList(pDfsVolList); Cleanup: if (pServerName != NULL) free(pServerName); if (pShareName != NULL) free(pShareName); if (fSwDebug == TRUE) MyPrintf(L"CmdLoad returning %d\r\n", dwErr); return dwErr; } DWORD DfspDomLoad( PDFS_VOLUME_LIST pDfsVolList, LPWSTR pDomName, LPWSTR pDfsName, LPWSTR pDcName) { DWORD dwErr = ERROR_SUCCESS; if (fSwDebug == TRUE) MyPrintf(L"CmdDomLoad(%ws,%ws,%ws)\r\n", pDomName, pDfsName, pDcName); MyPrintf(L"\\\\%ws\\%ws is a DomDfs\r\n", pDomName, pDfsName); dwErr = DfsGetFtVol( pDfsVolList, pDfsName, pDcName, pDomName, NULL); if (dwErr != ERROR_SUCCESS) goto Cleanup; if (fSwDebug == TRUE) DfsDumpVolList(pDfsVolList); Cleanup: if (fSwDebug == TRUE) MyPrintf(L"CmdDomLoad returning %d\r\n", dwErr); return dwErr; } DWORD DfspStdLoad( PDFS_VOLUME_LIST pDfsVolList, LPWSTR pServerName, LPWSTR pShareName, LPWSTR pDcName) { ULONG i; DWORD dwErr = ERROR_SUCCESS; BOOLEAN IsFtRoot = FALSE; WCHAR RootShare[MAX_PATH+1]; WCHAR DomDfsName[MAX_PATH+1]; LPWSTR pDomDfsName = NULL; DWORD cbName = sizeof(DomDfsName); DWORD dwType; HKEY hKey = NULL; HKEY rKey = NULL; if (fSwDebug == TRUE) MyPrintf(L"CmdStdLoad(%ws,%ws,%ws)\r\n", pServerName, pShareName, pDcName); ErrorMessage(MSG_CONNECTING, pServerName); // // See if this is a Fault-Tolerant Dfs vs Server-Based Dfs // dwErr = RegConnectRegistry( pServerName, HKEY_LOCAL_MACHINE, &rKey); if (dwErr != ERROR_SUCCESS) { ErrorMessage(MSG_CAN_NOT_CONNECT, pServerName); goto Cleanup; } dwErr = RegOpenKey(rKey, VOLUMES_DIR, &hKey); if (dwErr == ERROR_SUCCESS) { dwErr = RegQueryValueEx( hKey, FTDFS_VALUE_NAME, NULL, &dwType, (PBYTE) DomDfsName, &cbName); if (dwErr == ERROR_MORE_DATA) dwErr = ERROR_SUCCESS; if (dwErr == ERROR_SUCCESS && dwType == REG_SZ) IsFtRoot = TRUE; } else { MyPrintf(L"Not a Dfs root\r\n"); goto Cleanup; } dwErr = RegQueryValueEx( hKey, ROOT_SHARE_VALUE_NAME, NULL, &dwType, (PBYTE) RootShare, &cbName); if (dwErr == ERROR_MORE_DATA) dwErr = ERROR_SUCCESS; if (dwErr != ERROR_SUCCESS || dwType != REG_SZ) { MyPrintf(L"Registry value \"RootShare\" is missing or corrupt.\r\n"); goto Cleanup; } if (IsFtRoot == TRUE) { if (fSwDebug == TRUE) MyPrintf(L"Registry says is DomDfs (%ws)...\r\n", DomDfsName); if (pDomDfsName == NULL) { pDomDfsName = DomDfsName; } else { if (fSwDebug == TRUE) MyPrintf(L"You specified to check against %ws\r\n", pDomDfsName); } dwErr = DfsGetFtVol( pDfsVolList, pDomDfsName, pDcName, NULL, NULL); if (dwErr != ERROR_SUCCESS) goto Cleanup; dwErr = GetExitPtInfo( rKey, &pDfsVolList->pRootLocalVol, &pDfsVolList->cRootLocalVol); if (dwErr != ERROR_SUCCESS) goto Cleanup; } else { if (fSwDebug == TRUE) MyPrintf(L"Is StdDfs...\r\n"); dwErr = DfsGetStdVol( rKey, pDfsVolList); if (dwErr != ERROR_SUCCESS) goto Cleanup; dwErr = GetExitPtInfo( rKey, &pDfsVolList->pRootLocalVol, &pDfsVolList->cRootLocalVol); if (dwErr != ERROR_SUCCESS) goto Cleanup; } if (fSwDebug == TRUE) DfsDumpVolList(pDfsVolList); Cleanup: if (hKey != NULL) RegCloseKey(hKey); if (rKey != NULL) RegCloseKey(rKey); if (fSwDebug == TRUE) MyPrintf(L"CmdStdLoad returning %d\r\n", dwErr); return dwErr; } DWORD CmdSave( PDFS_VOLUME_LIST pDfsVolList, LPWSTR pDfsName, LPWSTR pDcName) { DWORD dwErr = ERROR_SUCCESS; LPWSTR pServerName = NULL; LPWSTR pShareName = NULL; BOOLEAN IsDomainName = FALSE; if (fSwDebug == TRUE) MyPrintf(L"CmdSave(%ws,%ws)\r\n", pDfsName, pDcName); if (pDfsName == NULL) { dwErr = ERROR_INVALID_PARAMETER; goto Cleanup; } dwErr = DfspParseName( pDfsName, &pServerName, &pShareName); if (dwErr != ERROR_SUCCESS) goto Cleanup; dwErr = DfspIsDomainName( pServerName, pDcName, &IsDomainName); if (dwErr != ERROR_SUCCESS) goto Cleanup; if (IsDomainName == TRUE) { dwErr = DfspDomSave( pDfsVolList, pServerName, pShareName, pDcName); } else { dwErr = DfspStdSave( pDfsVolList, pServerName, pShareName); } if (dwErr != ERROR_SUCCESS) goto Cleanup; Cleanup: if (pServerName != NULL) free(pServerName); if (pShareName != NULL) free(pShareName); if (fSwDebug == TRUE) MyPrintf(L"CmdSave returning %d\r\n", dwErr); return dwErr; } DWORD DfspDomSave( PDFS_VOLUME_LIST pDfsVolList, LPWSTR pDomName, LPWSTR pDfsName, LPWSTR pDcName) { DWORD dwErr = ERROR_SUCCESS; ULONG cbBlob = 0; BYTE *pBlob = NULL; WCHAR wszDcName[MAX_PATH+1]; if (fSwDebug == TRUE) MyPrintf(L"CmdDomSave(%ws,%ws,%ws)\r\n", pDomName, pDfsName, pDcName); MyPrintf(L"CmdDomSave(%ws,%ws,%ws)\r\n", pDomName, pDfsName, pDcName); MyPrintf(L"\\\\%ws\\%ws is a DomDfs\r\n", pDomName, pDfsName); if (pDcName == NULL) dwErr = DfspGetPdc(wszDcName, pDomName); else wcscpy(wszDcName, pDcName); if (dwErr != ERROR_SUCCESS) goto Cleanup; ErrorMessage(MSG_CONNECTING, wszDcName); // // Serialize // dwErr = DfsPutVolList( &cbBlob, &pBlob, pDfsVolList); if (dwErr != ERROR_SUCCESS) goto Cleanup; // // Update the DS // dwErr = DfsPutDsBlob( pDfsName, DfsConfigContainer, wszDcName, NULL, cbBlob, pBlob, pDfsVolList->RootServers); if (dwErr != ERROR_SUCCESS) goto Cleanup; MyPrintf(L"you need to reinit the dfs service on all roots of %ws\r\n", pDfsName); #if 0 dwErr = NetDfsManagerInitialize(pServerName, 0); #endif Cleanup: if (pBlob != NULL) free(pBlob); if (fSwDebug == TRUE) MyPrintf(L"CmdDomSave returning %d\r\n", dwErr); return dwErr; } DWORD DfspStdSave( PDFS_VOLUME_LIST pDfsVolList, LPWSTR pServerName, LPWSTR pShareName) { ULONG i; DWORD dwErr = ERROR_SUCCESS; BOOLEAN IsFtRoot = FALSE; WCHAR RootShare[MAX_PATH+1]; WCHAR DomDfsName[MAX_PATH+1]; LPWSTR pDomDfsName = NULL; DWORD cbName = sizeof(DomDfsName); DWORD dwType; HKEY hKey = NULL; HKEY rKey = NULL; if (fSwDebug == TRUE) MyPrintf(L"CmdStdSave(%ws,%ws)\r\n", pServerName, pShareName); MyPrintf(L"Writing metadata to %ws\n", pServerName); // // Verify that this is a Server-based Dfs // dwErr = RegConnectRegistry( pServerName, HKEY_LOCAL_MACHINE, &rKey); if (dwErr != ERROR_SUCCESS) { ErrorMessage(MSG_CAN_NOT_CONNECT, pServerName); goto Cleanup; } dwErr = RegOpenKey(rKey, VOLUMES_DIR, &hKey); if (dwErr != ERROR_SUCCESS) { MyPrintf(L"Not a Dfs root\r\n"); goto Cleanup; } dwErr = RegQueryValueEx( hKey, FTDFS_VALUE_NAME, NULL, &dwType, (PBYTE) DomDfsName, &cbName); if (dwErr == ERROR_MORE_DATA) dwErr = ERROR_SUCCESS; if (dwErr == ERROR_SUCCESS && dwType == REG_SZ) IsFtRoot = TRUE; dwErr = RegQueryValueEx( hKey, ROOT_SHARE_VALUE_NAME, NULL, &dwType, (PBYTE) RootShare, &cbName); if (dwErr == ERROR_MORE_DATA) dwErr = ERROR_SUCCESS; if (dwErr != ERROR_SUCCESS || dwType != REG_SZ) { MyPrintf(L"Registry value \"RootShare\" is missing or corrupt.\r\n"); goto Cleanup; } if (IsFtRoot == TRUE) { if (fSwDebug == TRUE) MyPrintf(L"Internal error: Registry says is DomDfs (%ws)...\r\n", DomDfsName); dwErr = ERROR_INTERNAL_ERROR; goto Cleanup; } dwErr = DfsSetStdVol( rKey, pDfsVolList); if (dwErr != ERROR_SUCCESS) goto Cleanup; MyPrintf(L"Reinitializing dfs service on %ws\n", pServerName); dwErr = NetDfsManagerInitialize(pServerName, 0); Cleanup: if (hKey != NULL) RegCloseKey(hKey); if (rKey != NULL) RegCloseKey(rKey); if (fSwDebug == TRUE) MyPrintf(L"CmdStdSave returning %d\r\n", dwErr); return dwErr; } DWORD CmdLinkMap( PDFS_VOLUME_LIST pDfsVolList, LPWSTR pLink, LPWSTR pShortLink, LPWSTR pComment, LPWSTR pTimeout, LPWSTR pState, LPWSTR pType, LPWSTR pGUID, ULONG LineNum) { DWORD dwErr = ERROR_SUCCESS; LONG Min; LONG Max; LONG Res; PDFS_VOLUME pVol = NULL; PVOID pVoid = NULL; LONG Cur = -1; LONG i; ULONG Size; LPWSTR pPrefix = NULL; LPWSTR pShortPrefix = NULL; if (fSwDebug == TRUE) MyPrintf(L"CmdLinkMap(%ws,%ws,%ws,%ws,%ws,%ws,%ws,%d)\r\n", pLink, pShortLink, pComment, pTimeout, pState, pType, pGUID, LineNum); // // Trim leading \'s // while (*pLink == UNICODE_PATH_SEP) pLink++; // // If no short prefix is given, use the long prefix // if (pShortLink == NULL) pShortLink = pLink; if(pDfsVolList == NULL){ dwErr = ERROR_INVALID_PARAMETER; goto Cleanup; } if(pDfsVolList->Volumes == NULL){ dwErr = ERROR_INVALID_PARAMETER; goto Cleanup; } // // Build full prefix and shortprefix names // Size = wcslen(pDfsVolList->Volumes[0]->wszPrefix) * sizeof(WCHAR) + sizeof(WCHAR) + wcslen(pLink) * sizeof(WCHAR) + sizeof(WCHAR); pPrefix = (LPWSTR) malloc(Size); if (pPrefix == NULL) { dwErr = ERROR_OUTOFMEMORY; goto Cleanup; } Size = wcslen(pDfsVolList->Volumes[0]->wszShortPrefix) * sizeof(WCHAR) + sizeof(WCHAR) + wcslen(pShortLink) * sizeof(WCHAR) + sizeof(WCHAR); pShortPrefix = (LPWSTR) malloc(Size); if (pShortPrefix == NULL) { dwErr = ERROR_OUTOFMEMORY; goto Cleanup; } wcscpy(pPrefix, pDfsVolList->Volumes[0]->wszPrefix); wcscat(pPrefix, UNICODE_PATH_SEP_STR); wcscat(pPrefix, pLink); wcscpy(pShortPrefix, pDfsVolList->Volumes[0]->wszShortPrefix); wcscat(pShortPrefix, UNICODE_PATH_SEP_STR); wcscat(pShortPrefix, pShortLink); // // See if this link is already there. Binary Search. // if (pDfsVolList->VolCount > 0) { Min = 0; Max = pDfsVolList->VolCount-1; while (Min <= Max) { Cur = (Min + Max) / 2; Res = _wcsicmp(pDfsVolList->Volumes[Cur]->wszPrefix, pPrefix); if (Res == 0) { // we skip it, it is ok. //dwErr = ERROR_DUP_NAME; MyPrintf(L"MAP line %d: duplicate link %ws (skipped)\r\n", LineNum, pPrefix); goto Cleanup; } else if (Res < 0) { Min = Cur + 1; } else { Max = Cur - 1; } } } // // Expand the list if necessary // if (pDfsVolList->VolCount >= pDfsVolList->AllocatedVolCount) { pVoid = realloc( pDfsVolList->Volumes, (pDfsVolList->AllocatedVolCount + INIT_LINK_COUNT) * sizeof(PDFS_VOLUME)); if (pVoid == NULL) { dwErr = ERROR_OUTOFMEMORY; goto Cleanup; } pDfsVolList->Volumes = (PDFS_VOLUME *) pVoid; RtlZeroMemory( &pDfsVolList->Volumes[pDfsVolList->AllocatedVolCount], INIT_LINK_COUNT * sizeof(PDFS_VOLUME)); pDfsVolList->AllocatedVolCount += INIT_LINK_COUNT; if (fSwDebug == TRUE) MyPrintf(L"CmdLinkMap:realloced to %d\r\n", pDfsVolList->AllocatedVolCount); } if ((pDfsVolList->VolCount % 1000) == 0) MyPrintf(L"%d\r\n", pDfsVolList->VolCount); if (Cur == -1) Cur = 0; else if (Res < 0) Cur++; if (Cur < (LONG)pDfsVolList->VolCount) { RtlMoveMemory( &pDfsVolList->Volumes[Cur+1], &pDfsVolList->Volumes[Cur], sizeof(PDFS_VOLUME) * (pDfsVolList->VolCount-(ULONG)Cur)); } // // Add the new // pDfsVolList->Volumes[Cur] = (PDFS_VOLUME) malloc(sizeof(DFS_VOLUME)); if (pDfsVolList->Volumes[Cur] == NULL) { dwErr = ERROR_OUTOFMEMORY; goto Cleanup; } RtlZeroMemory(pDfsVolList->Volumes[Cur], sizeof(DFS_VOLUME)); pVol = pDfsVolList->Volumes[Cur]; pVol->wszPrefix = pPrefix; pPrefix = NULL; pVol->wszShortPrefix = pShortPrefix; pVol->vFlags |= VFLAGS_MODIFY; pShortPrefix = NULL; if (pComment != NULL) { pVol->wszComment = (PWCHAR)malloc((wcslen(pComment)+1) * sizeof(WCHAR)); if (pVol->wszComment == NULL) { dwErr = ERROR_OUTOFMEMORY; goto Cleanup; } wcscpy(pVol->wszComment, pComment); } if (pGUID != NULL && wcslen(pGUID) == (sizeof(GUID) * 2)) StringToGuid(pGUID, &pVol->idVolume); else { dwErr = UuidCreate(&pVol->idVolume); if(dwErr != RPC_S_OK) { goto Cleanup; } } pVol->wszObjectName = (PWCHAR)malloc(92); if (pVol->wszObjectName == NULL) { dwErr = ERROR_OUTOFMEMORY; goto Cleanup; } RtlZeroMemory(pVol->wszObjectName, 92); wcscpy(pVol->wszObjectName, L"\\domainroot\\"); GuidToStringEx(&pVol->idVolume, &pVol->wszObjectName[12]); if (pType != NULL) { if (pType[0] == L'0' && (pType[1] == L'x' || pType[1] == L'X')) pVol->dwType = AtoHex(pType, &dwErr); else pVol->dwType = AtoDec(pType, &dwErr); if (dwErr != ERROR_SUCCESS) { MyPrintf(L"bad value %ws\r\n", pType); goto Cleanup; } } else { pVol->dwType = 0x1; } if (pState != NULL) { if (pState[0] == L'0' && (pState[1] == L'x' || pState[1] == L'X')) pVol->dwState = AtoHex(pState, &dwErr); else pVol->dwState = AtoDec(pState, &dwErr); if (dwErr != ERROR_SUCCESS) { MyPrintf(L"bad value %ws\r\n", pState); goto Cleanup; } } else { pVol->dwState = 0x1; } if (pTimeout != NULL) { if (pTimeout[0] == L'0' && (pTimeout[1] == L'x' || pTimeout[1] == L'X')) pVol->dwTimeout = AtoHex(pTimeout, &dwErr); else pVol->dwTimeout = AtoDec(pTimeout, &dwErr); if (dwErr != ERROR_SUCCESS) { MyPrintf(L"bad value %ws\r\n", pTimeout); goto Cleanup; } } else { pVol->dwTimeout = 300; } pVol->dwVersion = 3; pVol->ReplCount = 0; pVol->AllocatedReplCount = 0; pVol->vFlags |= VFLAGS_MODIFY; pDfsVolList->VolCount++; if (fSwDebug == TRUE) MyPrintf(L"CmdLinkMap exit %d\r\n", dwErr); return dwErr; Cleanup: // // We had a problem. Clean up and return the error // if (pVol != NULL) { if (pVol->wszObjectName != NULL) free(pVol->wszObjectName); if (pVol->wszPrefix != NULL) free(pVol->wszPrefix); if (pVol->wszShortPrefix != NULL) free(pVol->wszShortPrefix); if (pVol->wszComment != NULL) free(pVol->wszComment); RtlZeroMemory(pVol, sizeof(DFS_VOLUME)); } if (pPrefix != NULL) free(pPrefix); if (pShortPrefix != NULL) free(pShortPrefix); free(pgLink); pgLink = NULL; if (fSwDebug == TRUE) MyPrintf(L"CmdLinkMap exit %d\r\n", dwErr); return dwErr; } DWORD CmdLink( PDFS_VOLUME_LIST pDfsVolList, LPWSTR pLink, ULONG LineNum) { DWORD dwErr = ERROR_NOT_FOUND; LONG Min; LONG Max; LONG Res; LONG Cur = -1; LONG i; ULONG Size; LPWSTR pPrefix = NULL; if (fSwDebug == TRUE) MyPrintf(L"CmdLink(%ws,%d)\r\n", pLink, LineNum); // // Trim leading \'s // while (*pLink == UNICODE_PATH_SEP) pLink++; // // Build full prefix and shortprefix names // Size = wcslen(pDfsVolList->Volumes[0]->wszPrefix) * sizeof(WCHAR) + sizeof(WCHAR) + wcslen(pLink) * sizeof(WCHAR) + sizeof(WCHAR); pPrefix = (LPWSTR) malloc(Size); if (pPrefix == NULL) { dwErr = ERROR_OUTOFMEMORY; goto AllDone; } wcscpy(pPrefix, pDfsVolList->Volumes[0]->wszPrefix); wcscat(pPrefix, UNICODE_PATH_SEP_STR); wcscat(pPrefix, pLink); // // See if this link is there. Binary Search. // if (pDfsVolList->VolCount > 0) { Min = 0; Max = pDfsVolList->VolCount-1; while (Min <= Max) { Cur = (Min + Max) / 2; Res = _wcsicmp(pDfsVolList->Volumes[Cur]->wszPrefix, pPrefix); if (Res == 0) { dwErr = ERROR_SUCCESS; goto AllDone; } else if (Res < 0) { Min = Cur + 1; } else { Max = Cur - 1; } } } if (dwErr == ERROR_NOT_FOUND) MyPrintf(L"LINK line %d: link %ws not found (skipped)\r\n", LineNum, pLink); AllDone: if (pPrefix != NULL) free(pPrefix); if (dwErr != ERROR_SUCCESS) { free(pgLink); pgLink = NULL; } if (fSwDebug == TRUE) MyPrintf(L"CmdLink exit %d\r\n", dwErr); return dwErr; } DWORD CmdLinkUnmap( PDFS_VOLUME_LIST pDfsVolList, LPWSTR pLink, ULONG LineNum) { DWORD dwErr = ERROR_NOT_FOUND; LONG Min; LONG Max; LONG Res; PDFS_VOLUME pVol = NULL; LONG Cur = 0; LONG i; ULONG Size; PWCHAR wCp; BOOLEAN fPrefixAllocated = FALSE; LPWSTR pPrefix = NULL; if (fSwDebug == TRUE) MyPrintf(L"CmdLinkUnmap(%ws,%d)\r\n", pLink, LineNum); // // Allow two ways to specify a link // relative (no leading \\) // or absolute (leading \\) // // // Trim extra leading \'s // while (*pLink == UNICODE_PATH_SEP && *(pLink+1) == UNICODE_PATH_SEP) pLink++; if (*pLink == UNICODE_PATH_SEP) { if (*pLink == UNICODE_PATH_SEP && *(pLink+1) == UNICODE_PATH_SEP) pLink++; pPrefix = pLink; } else { // // Build full prefix name // Size = wcslen(pDfsVolList->Volumes[0]->wszPrefix) * sizeof(WCHAR) + sizeof(WCHAR) + wcslen(pLink) * sizeof(WCHAR) + sizeof(WCHAR); pPrefix = (LPWSTR) malloc(Size); if (pPrefix == NULL) { dwErr = ERROR_OUTOFMEMORY; goto Cleanup; } wcscpy(pPrefix, pDfsVolList->Volumes[0]->wszPrefix); wcscat(pPrefix, UNICODE_PATH_SEP_STR); wcscat(pPrefix, pLink); fPrefixAllocated = TRUE; } // // See if this link is there. Binary Search. // if (pDfsVolList->VolCount > 0) { Min = 0; Max = pDfsVolList->VolCount-1; while (Min <= Max) { Cur = (Min + Max) / 2; Res = _wcsicmp(pDfsVolList->Volumes[Cur]->wszPrefix, pPrefix); if (Res == 0) { dwErr = ERROR_SUCCESS; break; } else if (Res < 0) { Min = Cur + 1; } else { Max = Cur - 1; } } } if (dwErr != ERROR_SUCCESS) { MyPrintf(L"UNMAP line %d: link %ws not found (skipped)\r\n", LineNum, pLink); goto Cleanup; } if (fSwDebug == TRUE) MyPrintf(L"Found match at %d\r\n", Cur); pVol = pDfsVolList->Volumes[Cur]; if (pDfsVolList->DfsType == STDDFS) { pVol->vFlags |= VFLAGS_DELETE; } else if (pDfsVolList->DfsType == DOMDFS) { DfsFreeVol(pDfsVolList->Volumes[Cur]); free(pDfsVolList->Volumes[Cur]); RtlMoveMemory( &pDfsVolList->Volumes[Cur], &pDfsVolList->Volumes[Cur+1], sizeof(PDFS_VOLUME) * (pDfsVolList->VolCount-((ULONG)Cur)-1)); pDfsVolList->VolCount--; pDfsVolList->Volumes[pDfsVolList->VolCount] = NULL; } Cleanup: if (pPrefix != NULL && fPrefixAllocated == TRUE) free(pPrefix); if (dwErr != ERROR_SUCCESS) { free(pgLink); pgLink = NULL; } if (fSwDebug == TRUE) MyPrintf(L"CmdLinkUnmap exit %d\r\n", dwErr); return dwErr; } DWORD CmdLinkMod( PDFS_VOLUME_LIST pDfsVolList, LPWSTR pLink, LPWSTR pShortLink, LPWSTR pComment, LPWSTR pTimeout, LPWSTR pState, LPWSTR pType, LPWSTR pGUID, ULONG LineNum) { DWORD dwErr = ERROR_NOT_FOUND; LONG Min; LONG Max; LONG Res; PDFS_VOLUME pVol = NULL; LONG Cur = 0; LONG i; ULONG Size; PWCHAR wCp; BOOLEAN fPrefixAllocated = FALSE; LPWSTR pPrefix = NULL; LPWSTR pShortPrefix = NULL; if (fSwDebug == TRUE) MyPrintf(L"CmdLinkMod(%ws,%ws,%ws,%ws,%ws,%ws,%ws,%d)\r\n", pLink, pShortLink, pComment, pTimeout, pState, pType, pGUID, LineNum); // // Allow two ways to specify a link // relative (no leading \\) // or absolute (leading \\) // // // Trim extra leading \'s // while (*pLink == UNICODE_PATH_SEP && *(pLink+1) == UNICODE_PATH_SEP) pLink++; if (*pLink == UNICODE_PATH_SEP) { if (*pLink == UNICODE_PATH_SEP && *(pLink+1) == UNICODE_PATH_SEP) pLink++; pPrefix = pLink; } else { // // Build full prefix name // Size = wcslen(pDfsVolList->Volumes[0]->wszPrefix) * sizeof(WCHAR) + sizeof(WCHAR) + wcslen(pLink) * sizeof(WCHAR) + sizeof(WCHAR); pPrefix = (LPWSTR) malloc(Size); if (pPrefix == NULL) { dwErr = ERROR_OUTOFMEMORY; goto Cleanup; } wcscpy(pPrefix, pDfsVolList->Volumes[0]->wszPrefix); wcscat(pPrefix, UNICODE_PATH_SEP_STR); wcscat(pPrefix, pLink); fPrefixAllocated = TRUE; } // // See if this link is there. Binary Search. // if (pDfsVolList->VolCount > 0) { Min = 0; Max = pDfsVolList->VolCount-1; while (Min <= Max) { Cur = (Min + Max) / 2; Res = _wcsicmp(pDfsVolList->Volumes[Cur]->wszPrefix, pPrefix); if (Res == 0) { dwErr = ERROR_SUCCESS; break; } else if (Res < 0) { Min = Cur + 1; } else { Max = Cur - 1; } } } if (dwErr != ERROR_SUCCESS) { MyPrintf(L"MOD line %d: link %ws not found (skipped)\r\n", LineNum, pLink); goto Cleanup; } if (fSwDebug == TRUE) MyPrintf(L"Found match at %d\r\n", Cur); pVol = pDfsVolList->Volumes[Cur]; if (pShortLink != NULL) { while (*pShortLink == UNICODE_PATH_SEP) pShortLink++; Size = wcslen(pDfsVolList->Volumes[0]->wszShortPrefix) * sizeof(WCHAR) + sizeof(WCHAR) + wcslen(pShortLink) * sizeof(WCHAR) + sizeof(WCHAR); wCp = (LPWSTR) malloc(Size); if (wCp == NULL) { dwErr = ERROR_OUTOFMEMORY; goto Cleanup; } wcscpy(wCp, pDfsVolList->Volumes[0]->wszShortPrefix); wcscat(wCp, UNICODE_PATH_SEP_STR); wcscat(wCp, pShortLink); if (pVol->wszShortPrefix != NULL) free(pVol->wszShortPrefix); pVol->wszShortPrefix = wCp; } if (pComment != NULL) { wCp = (PWCHAR)malloc((wcslen(pComment)+1) * sizeof(WCHAR)); if (wCp == NULL) { dwErr = ERROR_OUTOFMEMORY; goto Cleanup; } if (pVol->wszComment != NULL) free(pVol->wszComment); pVol->wszComment = wCp; wcscpy(pVol->wszComment, pComment); } if (pGUID != NULL && wcslen(pGUID) == (sizeof(GUID) * 2)) StringToGuid(pGUID, &pVol->idVolume); if (pType != NULL) { if (pType[0] == L'0' && (pType[1] == L'x' || pType[1] == L'X')) pVol->dwType = AtoHex(pType, &dwErr); else pVol->dwType = AtoDec(pType, &dwErr); if (dwErr != ERROR_SUCCESS) { MyPrintf(L"bad value %ws\r\n", pType); goto Cleanup; } } if (pState != NULL) { if (pState[0] == L'0' && (pState[1] == L'x' || pState[1] == L'X')) pVol->dwState = AtoHex(pState, &dwErr); else pVol->dwState = AtoDec(pState, &dwErr); if (dwErr != ERROR_SUCCESS) { MyPrintf(L"bad value %ws\r\n", pState); goto Cleanup; } } if (pTimeout != NULL) { if (pTimeout[0] == L'0' && (pTimeout[1] == L'x' || pTimeout[1] == L'X')) pVol->dwTimeout = AtoHex(pTimeout, &dwErr); else pVol->dwTimeout = AtoDec(pTimeout, &dwErr); if (dwErr != ERROR_SUCCESS) { MyPrintf(L"bad value %ws\r\n", pTimeout); goto Cleanup; } } pVol->vFlags |= VFLAGS_MODIFY; Cleanup: if (pPrefix != NULL && fPrefixAllocated == TRUE) free(pPrefix); if (pShortPrefix != NULL) free(pShortPrefix); if (dwErr != ERROR_SUCCESS) { free(pgLink); pgLink = NULL; } if (fSwDebug == TRUE) MyPrintf(L"CmdLinkMod exit %d\r\n", dwErr); return dwErr; } DWORD CmdAdd( PDFS_VOLUME_LIST pDfsVolList, LPWSTR pLink, LPWSTR pAltName, LPWSTR pState, LPWSTR pType, ULONG LineNum) { DWORD dwErr = ERROR_NOT_FOUND; LONG Min; LONG Max; LONG Res; PDFS_VOLUME pVol = NULL; DFS_REPLICA_INFO *pReplInfo; LONG Cur = 0; PVOID pVoid; LPWSTR pPrefix = NULL; ULONG Size; if (fSwDebug == TRUE) MyPrintf(L"CmdAdd(%ws,%ws,%ws,%ws,%d)\r\n", pLink, pAltName, pState, pType, LineNum); if (pLink == NULL) { dwErr = ERROR_INVALID_PARAMETER; MyPrintf(L"ADD line %d: No link specified (skipped)\r\n", LineNum); goto Cleanup; } // // Trim leading \'s // while (*pLink == UNICODE_PATH_SEP) pLink++; // // Build full prefix name // Size = wcslen(pDfsVolList->Volumes[0]->wszPrefix) * sizeof(WCHAR) + sizeof(WCHAR) + wcslen(pLink) * sizeof(WCHAR) + sizeof(WCHAR); pPrefix = (LPWSTR) malloc(Size); if (pPrefix == NULL) { dwErr = ERROR_OUTOFMEMORY; goto Cleanup; } wcscpy(pPrefix, pDfsVolList->Volumes[0]->wszPrefix); wcscat(pPrefix, UNICODE_PATH_SEP_STR); wcscat(pPrefix, pLink); // // See if this link is there. Binary Search. // if (pDfsVolList->VolCount > 0) { Min = 0; Max = pDfsVolList->VolCount-1; while (Min <= Max) { Cur = (Min + Max) / 2; Res = _wcsicmp(pDfsVolList->Volumes[Cur]->wszPrefix, pPrefix); if (Res == 0) { dwErr = ERROR_SUCCESS; break; } else if (Res < 0) { Min = Cur + 1; } else { Max = Cur - 1; } } } if (dwErr != ERROR_SUCCESS) { MyPrintf(L"ADD line %d: link %ws not found (skipped)\r\n", LineNum, pPrefix); goto Cleanup; } pVol = pDfsVolList->Volumes[Cur]; if (fSwDebug == TRUE) MyPrintf(L"Found match at %d\r\n", Cur); if (pVol->ReplCount == 0) { pVol->ReplicaInfo = (DFS_REPLICA_INFO *) malloc( INIT_ALT_COUNT * sizeof(DFS_REPLICA_INFO)); if (pVol->ReplicaInfo == NULL) { dwErr = ERROR_OUTOFMEMORY; goto Cleanup; } RtlZeroMemory(pVol->ReplicaInfo, INIT_ALT_COUNT * sizeof(DFS_REPLICA_INFO)); pVol->ReplCount = 0; pVol->AllocatedReplCount = INIT_ALT_COUNT; } if (pVol->ReplCount >= (pVol->AllocatedReplCount-1)) { pVoid = realloc( pVol->ReplicaInfo, (pVol->AllocatedReplCount + INIT_ALT_COUNT) * sizeof(DFS_REPLICA_INFO)); if (pVoid == NULL) { dwErr = ERROR_OUTOFMEMORY; goto Cleanup; } pVol->ReplicaInfo = (DFS_REPLICA_INFO *) pVoid; RtlZeroMemory( &pVol->ReplicaInfo[pVol->ReplCount], INIT_ALT_COUNT * sizeof(DFS_REPLICA_INFO)); pVol->AllocatedReplCount += INIT_ALT_COUNT; } pReplInfo = &pVol->ReplicaInfo[pVol->ReplCount]; dwErr = DfspBreakName( pAltName, &pReplInfo->pwszServerName, &pReplInfo->pwszShareName); if (dwErr != ERROR_SUCCESS) goto Cleanup; if (pState != NULL) { if (pState[0] == L'0' && (pState[1] == L'x' || pState[1] == L'X')) pReplInfo->ulReplicaState = AtoHex(pState, &dwErr); else pReplInfo->ulReplicaState = AtoDec(pState, &dwErr); if (dwErr != ERROR_SUCCESS) { MyPrintf(L"bad value %ws\r\n", pState); goto Cleanup; } } else { pReplInfo->ulReplicaState = 0x2; } if (pType != NULL) { if (pType[0] == L'0' && (pType[1] == L'x' || pType[1] == L'X')) pReplInfo->ulReplicaType = AtoHex(pType, &dwErr); else pReplInfo->ulReplicaType = AtoDec(pType, &dwErr); if (dwErr != ERROR_SUCCESS) { MyPrintf(L"bad value %ws\r\n", pType); goto Cleanup; } } else { pReplInfo->ulReplicaType = 0x2; } pVol->ReplCount++; pVol->vFlags |= VFLAGS_MODIFY; Cleanup: if (pPrefix != NULL) free(pPrefix); if (fSwDebug == TRUE) MyPrintf(L"CmdAdd exit %d\r\n", dwErr); return dwErr; } DWORD CmdSiteMap( PDFS_VOLUME_LIST pDfsVolList, LPWSTR pServer, ULONG LineNum) { DWORD dwErr = ERROR_SUCCESS; PDFSM_SITE_ENTRY pSiteEntry = NULL; PLIST_ENTRY pListHead; PLIST_ENTRY pLink; LONG Res; if (fSwDebug == TRUE) MyPrintf(L"CmdSiteMap(%ws)\r\n", pServer); // // See if this server is already in the site table // pListHead = &pDfsVolList->SiteList; if (pListHead->Flink != NULL) { for (pLink = pListHead->Flink; pLink != pListHead; pLink = pLink->Flink) { pSiteEntry = CONTAINING_RECORD(pLink, DFSM_SITE_ENTRY, Link); Res = _wcsicmp(pSiteEntry->ServerName, pServer); if (Res == 0) { pSiteEntry = NULL; // we skip, it is ok. //dwErr = ERROR_DUP_NAME; MyPrintf(L"ADDSITE line %d: duplicate site %ws (skipped)\r\n", LineNum, pServer); pgSite = NULL; goto AllDone; } } } // // Not a dup - create a new one // pSiteEntry = (PDFSM_SITE_ENTRY) malloc(sizeof(DFSM_SITE_ENTRY)); if (pSiteEntry == NULL) { dwErr = ERROR_OUTOFMEMORY; goto AllDone; } RtlZeroMemory(pSiteEntry, sizeof(DFSM_SITE_ENTRY)); dwErr = DupString(&pSiteEntry->ServerName, pServer); if (dwErr != ERROR_SUCCESS) goto AllDone; // // Link it in // InsertHeadList(&pDfsVolList->SiteList, &pSiteEntry->Link); pDfsVolList->SiteCount++; pDfsVolList->sFlags |= VFLAGS_MODIFY; // // Indicate that we are done with the pSiteEntry // pSiteEntry = NULL; AllDone: if (pSiteEntry != NULL) { if (pSiteEntry->ServerName != NULL) free(pSiteEntry->ServerName); free(pSiteEntry); } if (fSwDebug == TRUE) MyPrintf(L"CmdSiteMap exit %d\n", dwErr); return dwErr; } DWORD CmdSite( PDFS_VOLUME_LIST pDfsVolList, LPWSTR pServer, ULONG LineNum) { DWORD dwErr = ERROR_NOT_FOUND; PDFSM_SITE_ENTRY pSiteEntry = NULL; PLIST_ENTRY pListHead; PLIST_ENTRY pLink; LONG Res; if (fSwDebug == TRUE) MyPrintf(L"CmdSite(%ws)\r\n", pServer); // // See if this server is in the site table // pListHead = &pDfsVolList->SiteList; if (pListHead->Flink != NULL) { for (pLink = pListHead->Flink; pLink != pListHead; pLink = pLink->Flink) { pSiteEntry = CONTAINING_RECORD(pLink, DFSM_SITE_ENTRY, Link); Res = _wcsicmp(pSiteEntry->ServerName, pServer); if (Res == 0) { dwErr = ERROR_SUCCESS; break; } } } if (dwErr != ERROR_SUCCESS) { MyPrintf(L"SITE line %d: link %ws not found (skipped)\r\n", LineNum, pServer); free(pgSite); pgSite = NULL; } if (fSwDebug == TRUE) MyPrintf(L"CmdSite exit %d\n", dwErr); return dwErr; } DWORD CmdAddSiteToServer( PDFS_VOLUME_LIST pDfsVolList, LPWSTR pServer, LPWSTR pSite, ULONG LineNum) { DWORD dwErr = ERROR_NOT_FOUND; PDFSM_SITE_ENTRY pSiteEntry = NULL; PDFSM_SITE_ENTRY pSiteEntryNew = NULL; PLIST_ENTRY pListHead; PLIST_ENTRY pLink; ULONG cSites; ULONG Size; LONG Res; if (fSwDebug == TRUE) MyPrintf(L"CmdAddSiteToServer(%ws,%ws)\r\n", pServer, pSite); if (pDfsVolList == NULL || pSite == NULL || pServer == NULL) { dwErr = ERROR_INVALID_PARAMETER; goto Cleanup; } // // See if this server is in the site table // pListHead = &pDfsVolList->SiteList; if (pListHead->Flink != NULL) { for (pLink = pListHead->Flink; pLink != pListHead; pLink = pLink->Flink) { pSiteEntry = CONTAINING_RECORD(pLink, DFSM_SITE_ENTRY, Link); Res = _wcsicmp(pSiteEntry->ServerName, pServer); if (Res == 0) { dwErr = ERROR_SUCCESS; break; } } } if (dwErr != ERROR_SUCCESS) { MyPrintf(L"ADD line %d: Server %ws not found (skipped)\r\n", LineNum, pServer); free(pgSite); pgSite = NULL; goto Cleanup; } // // Check if site already in the list // for (cSites = 0; cSites < pSiteEntry->Info.cSites; cSites++) { Res = _wcsicmp(pSiteEntry->Info.Site[cSites].SiteName, pSite); if (Res == 0) { //we skip, it is okay. //dwErr = ERROR_DUP_NAME; MyPrintf(L"ADD line %d: Site %ws: duplicate (skipped)\r\n", LineNum, pSite); pSiteEntry = NULL; goto Cleanup; } } cSites = pSiteEntry->Info.cSites + 1; Size = sizeof(DFSM_SITE_ENTRY) + cSites * sizeof(DFS_SITENAME_INFO); pSiteEntryNew = (PDFSM_SITE_ENTRY) malloc(Size); if (pSiteEntryNew == NULL) { dwErr = ERROR_OUTOFMEMORY; goto Cleanup; } RtlZeroMemory(pSiteEntryNew, Size); RtlMoveMemory(pSiteEntryNew, pSiteEntry, Size - sizeof(DFS_SITENAME_INFO)); // // Add the new site to the end // pSiteEntryNew->Info.Site[cSites-1].SiteFlags = 0; dwErr = DupString(&pSiteEntryNew->Info.Site[cSites-1].SiteName, pSite); if (dwErr != ERROR_SUCCESS) { pSiteEntry = NULL; goto Cleanup; } pSiteEntryNew->Info.cSites++; RemoveEntryList(&pSiteEntry->Link); InsertHeadList(&pDfsVolList->SiteList, &pSiteEntryNew->Link); pSiteEntryNew = NULL; Cleanup: if (pSiteEntryNew != NULL) free(pSiteEntryNew); if (pSiteEntry != NULL) free(pSiteEntry); if (fSwDebug == TRUE) MyPrintf(L"CmdAddSiteToServer exit %d\n", dwErr); return dwErr; } DWORD CmdSiteUnmap( PDFS_VOLUME_LIST pDfsVolList, LPWSTR pServer, ULONG LineNum) { DWORD dwErr = ERROR_NOT_FOUND; PDFSM_SITE_ENTRY pSiteEntry = NULL; PLIST_ENTRY pListHead; PLIST_ENTRY pLink; LONG Res; if (fSwDebug == TRUE) MyPrintf(L"CmdSiteUnnap(%ws)\r\n", pServer); // // See if this server is already in the site table // pListHead = &pDfsVolList->SiteList; if (pListHead->Flink != NULL) { for (pLink = pListHead->Flink; pLink != pListHead; pLink = pLink->Flink) { pSiteEntry = CONTAINING_RECORD(pLink, DFSM_SITE_ENTRY, Link); Res = _wcsicmp(pSiteEntry->ServerName, pServer); if (Res == 0) { RemoveEntryList(&pSiteEntry->Link); pDfsVolList->SiteCount--; pDfsVolList->sFlags |= VFLAGS_MODIFY; dwErr = ERROR_SUCCESS; goto AllDone; } } } pSiteEntry = NULL; MyPrintf(L"UNMAP line %d: server %ws not found (skipped)\r\n", LineNum, pServer); AllDone: if (pSiteEntry != NULL) { if (pSiteEntry->ServerName != NULL) free(pSiteEntry->ServerName); free(pSiteEntry); } if (fSwDebug == TRUE) MyPrintf(L"CmdSiteUnmap exit %d\n", dwErr); return dwErr; } DWORD DfspBreakName( LPWSTR pPath, LPWSTR *ppServerName, LPWSTR *ppShareName) { DWORD dwErr = ERROR_SUCCESS; LPWSTR pServerName = NULL; LPWSTR pShareName = NULL; WCHAR *wCp1 = NULL; WCHAR *wCp2 = NULL; ULONG Len = 0; if (fSwDebug == TRUE) MyPrintf(L"DfspBreakName(%ws)\r\n", pPath); wCp1 = pPath; while (*wCp1 == UNICODE_PATH_SEP && *wCp1 != UNICODE_NULL) wCp1++; if (*wCp1 == UNICODE_NULL) { dwErr = ERROR_INVALID_PARAMETER; goto Cleanup; } wCp2 = wCp1; while (*wCp2 != UNICODE_PATH_SEP && *wCp2 != UNICODE_NULL) wCp2++; if (*wCp2 == UNICODE_NULL) { dwErr = ERROR_INVALID_PARAMETER; goto Cleanup; } Len = (ULONG)((wCp2 - wCp1) * sizeof(WCHAR)); pServerName = (LPWSTR)malloc(Len + sizeof(WCHAR)); if (pServerName == NULL) { dwErr = ERROR_OUTOFMEMORY; goto Cleanup; } RtlZeroMemory(pServerName,Len+sizeof(WCHAR)); RtlCopyMemory(pServerName, wCp1, Len); wCp1 = wCp2; while (*wCp1 == UNICODE_PATH_SEP && *wCp1 != UNICODE_NULL) wCp1++; if (*wCp1 == UNICODE_NULL) { dwErr = ERROR_INVALID_PARAMETER; goto Cleanup; } wCp2 = wCp1; while (*wCp2 != UNICODE_NULL) wCp2++; Len = (ULONG)((wCp2 - wCp1) * sizeof(WCHAR)); pShareName = (LPWSTR)malloc(Len + sizeof(WCHAR)); if (pShareName == NULL) { dwErr = ERROR_OUTOFMEMORY; goto Cleanup; } RtlZeroMemory(pShareName,Len+sizeof(WCHAR)); RtlCopyMemory(pShareName, wCp1, Len); *ppServerName = pServerName; *ppShareName = pShareName; Cleanup: if (dwErr != ERROR_SUCCESS) { if (pServerName != NULL) free(pServerName); if (pShareName != NULL) free(pShareName); } if (fSwDebug == TRUE) MyPrintf(L"DfspBreakName returning %d\r\n", dwErr); return dwErr; } BOOLEAN CmdProcessInfileArg(LPWSTR Arg) { LONG ArgLen; BOOLEAN dwErr = FALSE; BOOLEAN FoundAnArg = FALSE; BOOLEAN FoundASwitch = FALSE; PWCHAR wCp = NULL; if (fSwDebug == TRUE) MyPrintf(L"ProcessInfileArg(%ws)\r\n", Arg); if ( Arg != NULL && wcslen(Arg) > 1) { dwErr = TRUE; ArgLen = wcslen(Arg); if (_wcsnicmp(Arg, ArgLink, ArgLenLink) == 0) { FoundAnArg = fArgLink = TRUE; if (ArgLen > ArgLenLink) { DupString(&pgLink, &Arg[ArgLenLink]); DupString(&pgSite, NULL); } } else if (_wcsnicmp(Arg, ArgSite, ArgLenSite) == 0) { FoundAnArg = fArgSite = TRUE; if (ArgLen > ArgLenSite) { DupString(&pgSite, &Arg[ArgLenSite]); DupString(&pgLink, NULL); } } else if (_wcsnicmp(Arg, ArgShortPrefix, ArgLenShortPrefix) == 0) { FoundAnArg = fArgShortPrefix = TRUE; if (ArgLen > ArgLenShortPrefix) pgShortLink = &Arg[ArgLenShortPrefix]; } else if (_wcsnicmp(Arg, ArgTimeout, ArgLenTimeout) == 0) { FoundAnArg = fArgTimeout = TRUE; if (ArgLen > ArgLenTimeout) pgTimeout = &Arg[ArgLenTimeout]; } else if (_wcsnicmp(Arg, ArgType, ArgLenType) == 0) { FoundAnArg = fArgType = TRUE; if (ArgLen > ArgLenType) pgType = &Arg[ArgLenType]; } else if (_wcsnicmp(Arg, ArgState, ArgLenState) == 0) { FoundAnArg = fArgState = TRUE; if (ArgLen > ArgLenState) pgState = &Arg[ArgLenState]; } else if (_wcsnicmp(Arg, ArgComment, ArgLenComment) == 0) { FoundAnArg = fArgComment = TRUE; if (ArgLen > ArgLenComment) pgComment = &Arg[ArgLenComment]; } else if (_wcsnicmp(Arg, ArgAdd, ArgLenAdd) == 0) { FoundAnArg = fArgAdd = TRUE; if (ArgLen > ArgLenAdd) pgAddArg = &Arg[ArgLenAdd]; } else if (_wcsnicmp(Arg, ArgGuid, ArgLenGuid) == 0) { FoundAnArg = fArgGuid = TRUE; if (ArgLen > ArgLenGuid) pgGuid = &Arg[ArgLenGuid]; } else if (_wcsnicmp(Arg, ArgDcName, ArgLenDcName) == 0) { FoundAnArg = fArgDcName = TRUE; if (ArgLen > ArgLenDcName) DupString(&pgDcName, &Arg[ArgLenDcName]); } else if (_wcsnicmp(Arg, ArgLoad, ArgLenLoad) == 0) { FoundAnArg = fArgLoad = TRUE; if (ArgLen > ArgLenLoad) DupString(&pgDfsName, &Arg[ArgLenLoad]); } else if (_wcsnicmp(Arg, ArgSave, ArgLenSave) == 0) { FoundAnArg = fArgSave = TRUE; if (ArgLen > ArgLenSave) DupString(&pgDfsName, &Arg[ArgLenSave]); } else if (_wcsnicmp(Arg, ArgAddRoot, ArgLenAddRoot) == 0) { FoundAnArg = fArgAddRoot = TRUE; if (ArgLen > ArgLenAddRoot) pgDomDfsName = &Arg[ArgLenAddRoot]; } else if (_wcsnicmp(Arg, ArgRemRoot, ArgLenRemRoot) == 0) { FoundAnArg = fArgRemRoot = TRUE; if (ArgLen > ArgLenRemRoot) pgDomDfsName = &Arg[ArgLenRemRoot]; } else if (_wcsnicmp(Arg, ArgServer, ArgLenServer) == 0) { FoundAnArg = fArgServer = TRUE; if (ArgLen > ArgLenServer) pgServerName = &Arg[ArgLenServer]; } else if (_wcsnicmp(Arg, ArgShare, ArgLenShare) == 0) { FoundAnArg = fArgShare = TRUE; if (ArgLen > ArgLenShare) pgShareName = &Arg[ArgLenShare]; } if (_wcsicmp(Arg, SwMap) == 0) { FoundASwitch = fSwMap = TRUE; } else if (_wcsicmp(Arg, SwUnMap) == 0) { FoundASwitch = fSwUnMap = TRUE; } else if (_wcsicmp(Arg, SwMod) == 0) { FoundASwitch = fSwMod = TRUE; } if (FoundAnArg == FALSE && FoundASwitch == FALSE) { ErrorMessage(MSG_UNRECOGNIZED_OPTION, Arg); dwErr = FALSE; goto AllDone; } } AllDone: if (fSwDebug == TRUE) MyPrintf(L"ProcessInfileArg exit %d\r\n", dwErr); return dwErr; } int _cdecl DfspVolCompare( const void *p1, const void *p2) { PDFS_VOLUME pVol1 = *((PDFS_VOLUME *) p1); PDFS_VOLUME pVol2 = *((PDFS_VOLUME *) p2); return _wcsicmp(pVol1->wszPrefix, pVol2->wszPrefix); } VOID DfspSortVolList( PDFS_VOLUME_LIST pDfsVolList) { ULONG i; PDFS_VOLUME *pVols = pDfsVolList->Volumes; if (pDfsVolList->VolCount < 2) return; for (i = 0; i < pDfsVolList->VolCount-1; i++) { if (_wcsicmp(pVols[i]->wszPrefix, pVols[i+1]->wszPrefix) > 0) { qsort(pVols, pDfsVolList->VolCount, sizeof(PDFS_VOLUME), DfspVolCompare); break; } } } DWORD DupString( LPWSTR *wCpp, LPWSTR s) { DWORD dwErr = ERROR_SUCCESS; if (*wCpp != NULL) { free(*wCpp); *wCpp = NULL; } if (s == NULL || wcslen(s) == 0) goto Cleanup; *wCpp = (LPWSTR)malloc((wcslen(s)+1) * sizeof(WCHAR)); if (*wCpp == NULL) { dwErr = ERROR_OUTOFMEMORY; goto Cleanup; } wcscpy(*wCpp, s); Cleanup: return dwErr; } DWORD CmdExport( LPWSTR pOutfile, LPWSTR pDomDfsName, LPWSTR pDcName, PSEC_WINNT_AUTH_IDENTITY pAuthIdent) { DWORD dwErr = ERROR_SUCCESS; HANDLE hFile = INVALID_HANDLE_VALUE; DFS_VOLUME_LIST DfsVolList = { 0 }; PDFS_VOLUME_LIST pDfsVolList = &DfsVolList; if (fSwDebug == TRUE) MyPrintf(L"CmdExport(%ws,%ws,%ws)\r\n", pOutfile, pDomDfsName, pDcName); hFile = CreateFile( pOutfile, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { dwErr = GetLastError(); goto Cleanup; } dwErr = CmdLoad( pDfsVolList, pDomDfsName, pDcName); if (dwErr != ERROR_SUCCESS) goto Cleanup; if(pDfsVolList != NULL) { if (pDfsVolList->RootServers != NULL) { // pDomDfSName is \\Dfs\Share, we just want Share LPWSTR pDfsName = pDomDfsName; for(int i=0; i<3 && pDfsName; pDfsName++){ if(*pDfsName == UNICODE_PATH_SEP) i++; } MyFPrintf(hFile, L"// uncomment the addroot lines if\r\n"); MyFPrintf(hFile, L"// you want the script to create the root\r\n"); for (ULONG cRoot = 0; pDfsVolList->RootServers[cRoot+1] != NULL; cRoot++) { LPWSTR pServer, pShare, pStr; // we start with \\server\share, need to split in two. // grab the share part pShare = pDfsVolList->RootServers[cRoot]; for(int i=0; i<3 && pShare; pShare++){ if(*pShare == UNICODE_PATH_SEP) i++; } // for the server we need to copy it... pServer = (LPWSTR) malloc(wcslen(pDfsVolList->RootServers[cRoot]) * sizeof(WCHAR)); if(pServer == NULL) { dwErr = ERROR_OUTOFMEMORY; goto Cleanup; } wcscpy(pServer, pDfsVolList->RootServers[cRoot]); pStr = pServer; for(int i=0; i<3 && pStr; pStr++){ if(*pStr == UNICODE_PATH_SEP) i++; } *(--pStr) = '\0'; // replace the '\' in server\share with '\0' MyFPrintf(hFile, L"// ADDROOT:%ws SERVER:%ws SHARE:%ws\r\n", pDfsName, pServer+2,// remove leading "\\" pShare); if(pServer) free(pServer); } } } MyFPrintf(hFile, L"// Load the dfs information\r\n"); MyFPrintf(hFile, L"LOAD:%ws ", pDomDfsName); if (pDcName != NULL) MyFPrintf(hFile, L"DCNAME:%ws\r\n", pDcName); MyFPrintf(hFile, L"\r\n"); MyFPrintf(hFile, L"\r\n"); DfspExportFile(hFile, pDfsVolList); MyFPrintf(hFile, L"// Save the dfs information\r\n"); MyFPrintf(hFile, L"SAVE:\r\n"); MyFPrintf(hFile, L"\r\n"); Cleanup: if (hFile != INVALID_HANDLE_VALUE) { FlushFileBuffers(hFile); CloseHandle(hFile); } DfsFreeVolList(pDfsVolList); if (fSwDebug == TRUE) MyPrintf(L"CmdExport exit %d\r\n", dwErr); return dwErr; } VOID DfspExportFile( HANDLE hHandle, PDFS_VOLUME_LIST pDfsVolList) { ULONG cVol; ULONG cRepl; ULONG cSite; ULONG i; PLIST_ENTRY pListHead; PLIST_ENTRY pLink; PDFSM_SITE_ENTRY pSiteEntry; WCHAR wszGuid[sizeof(GUID) * sizeof(WCHAR) + sizeof(WCHAR)]; DfspSortVolList(pDfsVolList); MyFPrintf(hHandle, L"// Link Information\r\n"); for (cVol = 1; cVol < pDfsVolList->VolCount; cVol++) { PWCHAR pPrefix = NULL; PWCHAR pShortPrefix = NULL; for (pPrefix = &pDfsVolList->Volumes[cVol]->wszPrefix[0]; pPrefix && *pPrefix != UNICODE_PATH_SEP; pPrefix++) NOTHING; // if we stopped here we would have dfsname\dfsshare\link // we want just link. if(pPrefix) pPrefix++; while(pPrefix && *pPrefix != UNICODE_PATH_SEP) pPrefix++; // do it twice if(pPrefix) pPrefix++; while(pPrefix && *pPrefix != UNICODE_PATH_SEP) pPrefix++; for (pShortPrefix = &pDfsVolList->Volumes[cVol]->wszShortPrefix[0]; pShortPrefix && *pShortPrefix != UNICODE_PATH_SEP; pShortPrefix++) NOTHING; // if we stopped here we would have dfsname\dfsshare\link // we want just link. if(pShortPrefix) pShortPrefix++; while(pShortPrefix && *pShortPrefix != UNICODE_PATH_SEP) pShortPrefix++; // do it twice if(pShortPrefix) pShortPrefix++; while(pShortPrefix && *pShortPrefix != UNICODE_PATH_SEP) pShortPrefix++; if(pPrefix) pPrefix++; if(pShortPrefix) pShortPrefix++; MyFPrintf(hHandle, L"LINK:%ws /MAP ", pPrefix); if (_wcsicmp(pPrefix, pShortPrefix) != 0) MyFPrintf(hHandle, L"SHORTPREFIX:%ws ", pShortPrefix); MyFPrintf( hHandle, L"GUID:%ws ", GuidToStringEx(&pDfsVolList->Volumes[cVol]->idVolume, wszGuid)); if (pDfsVolList->Volumes[cVol]->dwState != 0x1) MyFPrintf(hHandle, L"STATE:0x%x ", pDfsVolList->Volumes[cVol]->dwState); if (pDfsVolList->Volumes[cVol]->dwType != 0x1) MyFPrintf(hHandle, L"TYPE:0x%x ", pDfsVolList->Volumes[cVol]->dwState); if (pDfsVolList->Volumes[cVol]->dwTimeout != 300) MyFPrintf(hHandle, L"TIMEOUT:%d ", pDfsVolList->Volumes[cVol]->dwTimeout); if ( pDfsVolList->Volumes[cVol]->wszComment != NULL && wcslen(pDfsVolList->Volumes[cVol]->wszComment) > 0 ) MyFPrintf(hHandle, L"COMMENT:\"%ws\"", pDfsVolList->Volumes[cVol]->wszComment); MyFPrintf(hHandle, L"\r\n"); for (cRepl = 0; cRepl < pDfsVolList->Volumes[cVol]->ReplCount; cRepl++) { MyFPrintf(hHandle, L" ADD:\\\\%ws\\%ws ", pDfsVolList->Volumes[cVol]->ReplicaInfo[cRepl].pwszServerName, pDfsVolList->Volumes[cVol]->ReplicaInfo[cRepl].pwszShareName); if (pDfsVolList->Volumes[cVol]->ReplicaInfo[cRepl].ulReplicaState != 0x2) MyFPrintf( hHandle, L"STATE:0x%x ", pDfsVolList->Volumes[cVol]->ReplicaInfo[cRepl].ulReplicaState); if (pDfsVolList->Volumes[cVol]->ReplicaInfo[cRepl].ulReplicaType != 0x2) MyFPrintf( hHandle, L"TYPE:0x%x\r\n", pDfsVolList->Volumes[cVol]->ReplicaInfo[cRepl].ulReplicaType); MyFPrintf(hHandle, L"\r\n"); } MyFPrintf(hHandle, L"\r\n"); } pListHead = &pDfsVolList->SiteList; if (pListHead->Flink != NULL) { MyFPrintf(hHandle, L"// Site Information\r\n"); MyFPrintf(hHandle, L"\r\n"); for (pLink = pListHead->Flink; pLink != pListHead; pLink = pLink->Flink) { pSiteEntry = CONTAINING_RECORD(pLink, DFSM_SITE_ENTRY, Link); MyFPrintf(hHandle, L"SITE:%ws /MAP \r\n", pSiteEntry->ServerName); for (i = 0; i < pSiteEntry->Info.cSites; i++) { MyFPrintf(hHandle, L" ADD:%ws\r\n", pSiteEntry->Info.Site[i].SiteName); } MyFPrintf(hHandle, L"\r\n"); } MyFPrintf(hHandle, L"\r\n"); } return; }