VOID LogfClose(PLOGFILE LogFile, BOOL ForceClose) { if (LogFile == NULL) return; if ((ForceClose == FALSE) && (LogFile->Permanent == TRUE)) return; RtlAcquireResourceExclusive(&LogFile->Lock, TRUE); FlushFileBuffers(LogFile->hFile); CloseHandle(LogFile->hFile); LogfListRemoveItem(LogFile); RtlDeleteResource(&LogFile->Lock); HeapFree(MyHeap, 0, LogFile->LogName); HeapFree(MyHeap, 0, LogFile->FileName); HeapFree(MyHeap, 0, LogFile->OffsetInfo); HeapFree(MyHeap, 0, LogFile); return; }
static int wine_pthread_rwlock_destroy(pthread_rwlock_t *rwlock) { if (!((wine_rwlock)rwlock)->lock) return 0; RtlDeleteResource(((wine_rwlock)rwlock)->lock); RtlFreeHeap(GetProcessHeap(), 0, ((wine_rwlock)rwlock)->lock); return 0; }
static void rwlock_real_init(pthread_rwlock_t *rwlock) { RTL_RWLOCK *lock = RtlAllocateHeap(GetProcessHeap(), 0, sizeof(RTL_RWLOCK)); RtlInitializeResource(lock); if (interlocked_cmpxchg_ptr((void**)&(((wine_rwlock)rwlock)->lock),lock,NULL) != NULL) { /* too late, some other thread already did it */ RtlDeleteResource(lock); RtlFreeHeap(GetProcessHeap(), 0, lock); } }
VOID LogfClose(PLOGFILE LogFile, BOOLEAN ForceClose) { if (LogFile == NULL) return; if (!ForceClose && LogFile->Permanent) return; RtlAcquireResourceExclusive(&LogFile->Lock, TRUE); LogfListRemoveItem(LogFile); ElfCloseFile(&LogFile->LogFile); NtClose(LogFile->FileHandle); RtlFreeHeap(GetProcessHeap(), 0, LogFile->LogName); RtlDeleteResource(&LogFile->Lock); RtlFreeHeap(GetProcessHeap(), 0, LogFile); return; }
NET_API_STATUS BrDestroyNetwork( IN PNETWORK Network, IN PVOID Context ) /*++ Routine Description: This routine removes a reference to a network. If the network reference count goes to 0, remove the network. Arguments: Network - The network to remove Return Value: Status of operation (mostly status of allocations). --*/ { NTSTATUS Status; Status = RtlEnterCriticalSection(&NetworkLock); if (!NT_SUCCESS(Status)) { InternalError(("Unable to acquire browser critical section\n")); return BrMapStatus(Status); } RemoveEntryList(&Network->NextNet); Status = RtlLeaveCriticalSection(&NetworkLock); if (!NT_SUCCESS(Status)) { InternalError(("Unable to release browser critical section\n")); return BrMapStatus(Status); } if (Network->Role & ROLE_MASTER) { // // Stop being the master on this network. This means removing // our name from the bowser driver and forcing an election. // BrStopMaster(Network); } if (Network->Role & (ROLE_POTENTIAL_BACKUP | ROLE_BACKUP)) { // // Stop being a backup on this network. This means downgrading our // machine to idle. // BrStopBackup(Network); } // // Ensure that there are no browser related names active in the browser. // BrUpdateBrowserStatus(Network, 0); UninitializeInterimServerList(&Network->BrowseTable); UninitializeInterimServerList(&Network->DomainList); if (Network->BackupServerList != NULL) { MIDL_user_free(Network->BackupServerList); } if (Network->BackupDomainList != NULL) { MIDL_user_free(Network->BackupDomainList); } // RtlDeleteCriticalSection(&Network->Lock); RtlDeleteResource(&Network->Lock); RtlDeleteCriticalSection(&Network->MasterFlagsLock); BrDestroyTimer(&Network->MasterBrowserAnnouncementTimer); BrDestroyTimer(&Network->MasterBrowserTimer); BrDestroyTimer(&Network->BackupBrowserTimer); BrDestroyResponseCache(Network); RtlDeleteCriticalSection(&Network->ResponseCacheLock); MIDL_user_free(Network->NetworkName.Buffer); if (Network->MasterBrowserName.Buffer != NULL) { MIDL_user_free(Network->MasterBrowserName.Buffer); } MIDL_user_free(Network); return NERR_Success; UNREFERENCED_PARAMETER(Context); }
NET_API_STATUS BrCreateNetwork( PUNICODE_STRING TransportName, IN BOOLEAN Wannish, IN BOOLEAN Ras, IN PUNICODE_STRING AlternateTransportName OPTIONAL ) /*++ Routine Description: This routine allocates memory to hold a network structure, and initializes all of its associated data structures. Arguments: TransportName - The name of the transport to add. Return Value: Status of operation (mostly status of allocations). --*/ { NET_API_STATUS Status; PNETWORK Network; BOOLEAN NetworkLockInitialized = FALSE; BOOLEAN MasterFlagsInitialized = FALSE; BOOLEAN BackupBrowserTimerCreated = FALSE; BOOLEAN MasterBrowserTimerCreated =FALSE; BOOLEAN AnnouncementTimerCreated = FALSE; BOOLEAN ResponseCacheLockInitialized = FALSE; // // Check to see if the transport already exists. // if ((Network = BrFindNetwork(TransportName)) != NULL) { return NERR_AlreadyExists; } // // If this transport is explicitly on our list of transports to unbind, // simply ignore the transport. // if (BrInfo.UnboundBindings != NULL) { LPTSTR_ARRAY TStrArray = BrInfo.UnboundBindings; while (!NetpIsTStrArrayEmpty(TStrArray)) { LPWSTR NewTransportName; #define NAME_PREFIX L"\\Device\\" #define NAME_PREFIX_LENGTH 8 // // The transport name in the registry is only optionally prefixed with \device\ // if ( _wcsnicmp( NAME_PREFIX, TStrArray, NAME_PREFIX_LENGTH) == 0 ) { NewTransportName = TransportName->Buffer; } else { NewTransportName = TransportName->Buffer + NAME_PREFIX_LENGTH; } if ( _wcsicmp( TStrArray, NewTransportName ) == 0 ) { dprintf(INIT, ("Binding is marked as unbound: %s (Silently ignoring)\n", TransportName->Buffer )); return NERR_Success; } TStrArray = NetpNextTStrArrayEntry(TStrArray); } } // // If this transport isn't bound to the SMB server, // don't create the transport here. // we do announcments through the SMB server. // Status = I_NetServerSetServiceBits(NULL, TransportName->Buffer, 0, TRUE); if (Status == ERROR_PATH_NOT_FOUND ) { dprintf(INIT, ("SMB Server doesn't have this transport: %s (Silently unbinding)\n", TransportName->Buffer )); return NERR_Success; } // // Create the transport. // try { Network = MIDL_user_allocate(sizeof(NETWORK)); if (Network == NULL) { try_return(Status = ERROR_NOT_ENOUGH_MEMORY); } RtlInitializeResource(&Network->Lock); NetworkLockInitialized = TRUE; Network->LockCount = 0; Network->ReferenceCount = 1; Network->Role = BrDefaultRole; Network->NumberOfFailedBackupTimers = 0; Network->NumberOfFailedPromotions = 0; Network->NumberOfPromotionEventsLogged = 0; Network->LastBackupBrowserReturned = 0; Network->LastDomainControllerBrowserReturned = 0; Network->TimeStoppedBackup = 0; Network->BackupServerList = NULL; Network->BackupDomainList = NULL; Network->TotalBackupServerListEntries = 0; Network->TotalBackupDomainListEntries = 0; Network->NetworkName.Buffer = MIDL_user_allocate(TransportName->MaximumLength); if (Network->NetworkName.Buffer == NULL) { try_return(Status = ERROR_NOT_ENOUGH_MEMORY); } Network->NetworkName.MaximumLength = TransportName->MaximumLength; RtlCopyUnicodeString(&Network->NetworkName, TransportName); Network->Flags = 0; if (ARGUMENT_PRESENT(AlternateTransportName)) { PNETWORK AlternateNetwork = BrFindNetwork(AlternateTransportName); // // If we didn't find an alternate network, or if that network // already has an alternate network, return an error. // if (AlternateNetwork == NULL || AlternateNetwork->AlternateNetwork != NULL) { try_return(Status = NERR_InternalError); } Network->Flags |= NETWORK_IPX; // // Link the two networks together. // Network->AlternateNetwork = AlternateNetwork; AlternateNetwork->AlternateNetwork = Network; } else { Network->AlternateNetwork = NULL; } // // Null terminate the network name buffer. // Network->NetworkName.Buffer[Network->NetworkName.Length/sizeof(WCHAR)] = UNICODE_NULL; RtlInitUnicodeString(&Network->MasterBrowserName, NULL); if (Wannish) { Network->Flags |= NETWORK_WANNISH; } if (Ras) { Network->Flags |= NETWORK_RAS; } Network->LastBowserServerQueried = 0; RtlInitializeCriticalSection(&Network->MasterFlagsLock); MasterFlagsInitialized = TRUE; Network->MasterFlags = 0; InitializeInterimServerList(&Network->BrowseTable, BrBrowseTableInsertRoutine, BrBrowseTableUpdateRoutine, BrBrowseTableDeleteRoutine, BrBrowseTableAgeRoutine); Network->LastBowserDomainQueried = 0; InitializeInterimServerList(&Network->DomainList, BrDomainTableInsertRoutine, BrDomainTableUpdateRoutine, BrDomainTableDeleteRoutine, BrDomainTableAgeRoutine); InitializeListHead(&Network->OtherDomainsList); Status = BrCreateTimer(&Network->BackupBrowserTimer); if (Status != NERR_Success) { try_return(Status); } BackupBrowserTimerCreated = TRUE; Status = BrCreateTimer(&Network->MasterBrowserTimer); if (Status != NERR_Success) { try_return(Status); } MasterBrowserTimerCreated = TRUE; Status = BrCreateTimer(&Network->MasterBrowserAnnouncementTimer); if (Status != NERR_Success) { try_return(Status); } AnnouncementTimerCreated = TRUE; InitializeCriticalSection(&Network->ResponseCacheLock); ResponseCacheLockInitialized = TRUE; InitializeListHead(&Network->ResponseCache); Network->TimeCacheFlushed = 0; Network->NumberOfCachedResponses = 0; Status = RtlEnterCriticalSection(&NetworkLock); if (!NT_SUCCESS(Status)) { try_return(Status = BrMapStatus(Status)); } InsertHeadList(&ServicedNetworks, &Network->NextNet); Status = RtlLeaveCriticalSection(&NetworkLock); if (!NT_SUCCESS(Status)) { InternalError(("Unable to release browser critical section\n")); } try_exit:NOTHING; } finally { if (Status != NERR_Success) { if (Network != NULL) { if (ResponseCacheLockInitialized) { DeleteCriticalSection(&Network->ResponseCacheLock); } if (MasterFlagsInitialized) { RtlDeleteCriticalSection(&Network->MasterFlagsLock); } if (NetworkLockInitialized) { RtlDeleteResource(&Network->Lock); } if (AnnouncementTimerCreated) { BrDestroyTimer(&Network->MasterBrowserAnnouncementTimer); } if (MasterBrowserTimerCreated) { BrDestroyTimer(&Network->MasterBrowserTimer); } if (BackupBrowserTimerCreated) { BrDestroyTimer(&Network->BackupBrowserTimer); } if (Network->NetworkName.Buffer != NULL) { MIDL_user_free(Network->NetworkName.Buffer); } MIDL_user_free(Network); } } } return Status; }
VOID FreeModuleAndLogFileStructs ( ) /*++ Routine Description: This routine walks the module and log file list and frees all the data structures. Arguments: NONE Return Value: NONE Note: The file header and ditry bits must have been dealt with before this routine is called. Also, the file must have been unmapped and the handle closed. --*/ { NTSTATUS Status; PLOGMODULE pModule; PLOGFILE pLogFile; ElfDbgPrint (("[ELF] Freeing module and log file structs\n")); // // First free all the modules // while (!IsListEmpty (&LogModuleHead) ) { pModule = (PLOGMODULE) CONTAINING_RECORD(LogModuleHead.Flink, LOGMODULE, ModuleList); UnlinkLogModule(pModule); // Remove from linked list ElfpFreeBuffer (pModule); // Free module memory } // // Now free all the logfiles // while (!IsListEmpty (&LogFilesHead) ) { pLogFile = (PLOGFILE) CONTAINING_RECORD(LogFilesHead.Flink, LOGFILE, FileList); Status = ElfpCloseLogFile ( pLogFile, ELF_LOG_CLOSE_NORMAL); UnlinkLogFile(pLogFile); // Unlink the structure RtlDeleteResource ( &pLogFile->Resource ); ElfpFreeBuffer (pLogFile->LogFileName); ElfpFreeBuffer (pLogFile); } }
VOID ElfpCleanUp ( ULONG EventFlags ) /*++ Routine Description: This routine cleans up before the service terminates. It cleans up based on the parameter passed in (which indicates what has been allocated and/or started. Arguments: Bit-mask indicating what needs to be cleaned up. Return Value: NONE Note: It is expected that the RegistryMonitor has already been notified of Shutdown prior to calling this routine. --*/ { DWORD status = NO_ERROR; ElfDbgPrint (("[ELF] ElfpCleanUp.\n")); // // Notify the Service Controller for the first time that we are // about to stop the service. // // *** STATUS UPDATE *** ElfStatusUpdate(STOPPING); // // Stop the RPC Server // if (EventFlags & ELF_STARTED_RPC_SERVER) { ElfDbgPrint (("[ELF] Stopping the RPC Server.\n")); status = ElfGlobalData->StopRpcServer(eventlog_ServerIfHandle); if (status != NO_ERROR) { ElfDbgPrint (("[ELF] Stopping RpcServer Failed %d\n",status)); } } // // Stop the LPC thread // if (EventFlags & ELF_STARTED_LPC_THREAD) StopLPCThread(); // // Tell service controller that we are making progress // // *** STATUS UPDATE *** ElfStatusUpdate(STOPPING); // // Flush all the log files to disk. // ElfDbgPrint (("[ELF] Flushing Files.\n")); ElfpFlushFiles(); // // Tell service controller that we are making progress // ElfStatusUpdate(STOPPING); // // Clean up any resources that were allocated // FreeModuleAndLogFileStructs(); // // Free up memory // if (LocalComputerName) { ElfpFreeBuffer(LocalComputerName); } // // If we queued up any events, flush them // ElfDbgPrint (("[ELF] Flushing QueuedEvents.\n")); FlushQueuedEvents(); // // Tell service controller of that we are making progress // ElfStatusUpdate(STOPPING); if (EventFlags & ELF_INIT_GLOBAL_RESOURCE) RtlDeleteResource ( &GlobalElfResource ); if (EventFlags & ELF_INIT_LOGHANDLE_CRIT_SEC) RtlDeleteCriticalSection((PRTL_CRITICAL_SECTION)&LogHandleCritSec); if (EventFlags & ELF_INIT_LOGFILE_CRIT_SEC) RtlDeleteCriticalSection((PRTL_CRITICAL_SECTION)&LogFileCritSec); if (EventFlags & ELF_INIT_QUEUED_EVENT_CRIT_SEC) RtlDeleteCriticalSection((PRTL_CRITICAL_SECTION)&QueuedEventCritSec); // *** STATUS UPDATE *** ElfDbgPrint(("[ELF] Leaving the Eventlog service\n")); ElfStatusUpdate(STOPPED); ElCleanupStatus(); return; }