Example #1
0
//
// возвращает размер зан¤той списком файлов пам¤ти в байтах
//
BOOLEAN GetFileListSizeByBytes(PULONG pdwSize)
{
  BOOLEAN         bRes = FALSE;
  KDLinkedListItem* pNode;
  PFILEINFO       pFileInfo;

  if (
      KeGetCurrentIrql() == PASSIVE_LEVEL &&
      _MmIsAddressValid(pdwSize) &&
      _MmIsAddressValid(pSaveList)
     )
  {
    *pdwSize = 0;

    MUTEX_WAIT(LockMutexToFileSaveList);

    pNode = pSaveList->GetHead();
    while (_MmIsAddressValid(pNode))
    {
      pFileInfo = (PFILEINFO)pNode->GetObject();
      if (_MmIsAddressValid(pFileInfo))
      {
        *pdwSize += pFileInfo->dwSizeAllNamesArea + SIZEOF_FILEINFO_REAL;
      }
      pNode = pNode->GetNext();
    }

    MUTEX_RELEASE(LockMutexToFileSaveList);

    bRes = TRUE;
  }

  return bRes;
}
Example #2
0
File: ips.c Project: xinhaoyuan/cox
void
mutex_release(mutex_t mutex)
{
    proc_t notify = NULL;
    if (!MUTEX_HOLD(mutex)) return;
    
    int irq = __irq_save();
    spinlock_acquire(&mutex->lock);
    if (MUTEX_WAIT(mutex))
    {
        ips_node_t node = MUTEX_PTR(mutex);
        IPS_NODE_WAIT_CLEAR(node);
          
        notify = IPS_NODE_PTR(node);
        node->next->prev = node->prev;
        node->prev->next = node->next;
          
        if (node->next == node)
            MUTEX_WAIT_CLEAR(mutex);
        else MUTEX_PTR_SET(mutex, node->next);
    }
    else MUTEX_HOLD_CLEAR(mutex);
    spinlock_release(&mutex->lock);
    __irq_restore(irq);

    if (notify != NULL)
        proc_notify(notify);
}
Example #3
0
File: ips.c Project: xinhaoyuan/cox
int
mutex_acquire(mutex_t mutex, ips_node_t node)
{
    if (node == NULL)
    {
        ips_node_s node;
        if (!mutex_acquire(mutex, &node))
        {
            ips_wait(&node);
            return 0;
        }
        else return 1;
    }
    else
    {
        int irq = __irq_save();
        spinlock_acquire(&mutex->lock);
          
        if (!MUTEX_HOLD(mutex))
        {
            MUTEX_HOLD_SET(mutex);
            MUTEX_WAIT_CLEAR(mutex);
               
            spinlock_release(&mutex->lock);
            __irq_restore(irq);
               
            IPS_NODE_WAIT_CLEAR(node);
            
            return 1;
        }
        else
        {
            ips_wait_init(node, current);
               
            if (MUTEX_WAIT(mutex))
            {
                node->next = MUTEX_PTR(mutex);
                node->prev = node->next->prev;
                node->next->prev = node;
                node->prev->next = node;
            }
            else
            {
                MUTEX_WAIT_SET(mutex);
                node->next = node->prev = node;
                MUTEX_PTR_SET(mutex, node);
            }
               
            spinlock_release(&mutex->lock);
            __irq_restore(irq);

            return 0;
        }
    }
}
Example #4
0
static void
meet(
    void)
{
    MUTEX_LOCK(&mutex);
    while (!(waita && waitb)) {
        DEBUG_PRINT1("C Waiting");
        MUTEX_WAIT(&waitc, &mutex);
    }
    DEBUG_PRINT1("C Continuing");
    MUTEX_UNLOCK(&mutex);
}
Example #5
0
BOOLEAN GetFileSaveList(PFILEINFOSET pFileInfoSet)
{           
  BOOLEAN         bRes = FALSE;
  KDLinkedListItem* pNode;
  PFILEINFO       pFileInfo, pFileInfoDest;
  ULONG           dwSize;

  if (
      KeGetCurrentIrql() == PASSIVE_LEVEL &&
      _MmIsAddressValid(pSaveList) &&
      _MmIsAddressValid(pFileInfoSet)  &&
      pFileInfoSet->dwSize >= SIZEOF_FILEINFOSET
     )
  {
    dwSize = pFileInfoSet->dwSize;
    memset(pFileInfoSet, 0, dwSize);
    dwSize -= sizeof(ULONG);
    pFileInfoDest = &pFileInfoSet->FileInfo[0];

    MUTEX_WAIT(LockMutexToFileSaveList);

    pNode = pSaveList->GetHead();
    while (_MmIsAddressValid(pNode))
    {
      pFileInfo = (PFILEINFO)pNode->GetObject();
      if (_MmIsAddressValid(pFileInfo))
      {
        if (dwSize >= (pFileInfo->dwSizeAllNamesArea + SIZEOF_FILEINFO_REAL))
        {
          memcpy(pFileInfoDest, pFileInfo, (pFileInfo->dwSizeAllNamesArea + SIZEOF_FILEINFO_REAL));
//          if (dwSize >= (pFileInfo->dwSizeAllNamesArea + SIZEOF_FILEINFO_REAL))
            dwSize -= (pFileInfo->dwSizeAllNamesArea + SIZEOF_FILEINFO_REAL);
//          else
//            dwSize = 0;
          pFileInfoDest = (PFILEINFO)((CHAR*)pFileInfoDest + (pFileInfo->dwSizeAllNamesArea + SIZEOF_FILEINFO_REAL));
          pFileInfoSet->dwSize += (pFileInfo->dwSizeAllNamesArea + SIZEOF_FILEINFO_REAL);
        }
      }
      pNode = pNode->GetNext();
    }

    MUTEX_RELEASE(LockMutexToFileSaveList);

    if (pFileInfoSet->dwSize != 0)
      pFileInfoSet->dwSize += sizeof(ULONG);

    bRes = TRUE;
  }

  return bRes;
}
Example #6
0
static void
holdb(
    void)
{
    MUTEX_LOCK(&mutex);
    waitb = 1;
    DEBUG_PRINT1("B Broadcast C");
    MUTEX_BROADCAST(&waitc);
    while (waitb) {
        DEBUG_PRINT1("B Waiting");
        MUTEX_WAIT(&condb, &mutex);
    }
    DEBUG_PRINT1("B Continuing");
    MUTEX_UNLOCK(&mutex);
}
Example #7
0
static void
holda(
    void)
{
    MUTEX_LOCK(&mutex);
    waita = 1;
    DEBUG_PRINT1("A Broadcast C");
    MUTEX_BROADCAST(&waitc);
    while (waita) {
        DEBUG_PRINT1("A Waiting");
        MUTEX_WAIT(&conda, &mutex);
    }
    DEBUG_PRINT1("A Continuing");
    MUTEX_UNLOCK(&mutex);
}
Example #8
0
//******************************************************************//
//********************* List destroy functions *********************//
//******************************************************************//
void ClearSaveFileList(void)
{
  PFILEINFO       lpFileInfo;
  KDLinkedListItem* lpNode;

  __try
  {
    MUTEX_WAIT(LockMutexToFileSaveList);

    if (_MmIsAddressValid(pDirTree))
      delete pDirTree;
    pDirTree = NULL;
    
    if (_MmIsAddressValid(pSaveList))
    {
      lpNode = pSaveList->GetHead();
      while (_MmIsAddressValid(lpNode))
      {
        lpFileInfo = (PFILEINFO)pSaveList->RemoveHead();
        if (_MmIsAddressValid(lpFileInfo))
        {
          FreePoolToKHeap(hKHeapSOFileList, lpFileInfo); 
        }
        lpNode = pSaveList->GetHead();
      }
      delete pSaveList;
      pSaveList = NULL;
    }

    MUTEX_RELEASE(LockMutexToFileSaveList);
  }
  __except(EXCEPTION_EXECUTE_HANDLER)
  {
    MUTEX_RELEASE(LockMutexToFileSaveList);
    DbgPrintSO(("He4HookInv: ClearSaveFileList: EXCEPTION\n"));
  }
}
Example #9
0
/* run procthread */
void procthread_run(void *arg)
{
    PROCTHREAD *pth = (PROCTHREAD *)arg;
    int i = 0, usec = 0, sec = 0;
    struct timeval tv = {0,0};
    struct timespec ts = {0, 0};
    int k = 0, n = 0, policy = 0;

    if(pth)
    {
        struct sched_param param;
        pthread_getschedparam(pthread_self(), &policy, &param);
        ACCESS_LOGGER(pth->logger, "Ready for running thread[%p] policy:%d SCHED_FIFO:%d SCHED_RR:%d SCHED_OTHER:%d", (void*)((long)(pth->threadid)), policy, SCHED_FIFO, SCHED_RR, SCHED_OTHER);
        pth->running_status = 1;
        if(pth->usec_sleep > 1000000) sec = pth->usec_sleep/1000000;
        usec = pth->usec_sleep % 1000000;
        tv.tv_sec = sec;
        tv.tv_usec = usec;
        ts.tv_sec = sec;
        ts.tv_nsec = (long)usec * 1000l;
        if(pth->have_evbase)
        {
            if(pth->cond > 0)
            {
                event_set(&(pth->event), pth->cond, E_READ|E_PERSIST,
                        (void *)pth, (void *)&procthread_event_handler);
                pth->evbase->add(pth->evbase, &(pth->event));
                if(pth->service->flag & SB_LOG_THREAD)
                {
                    char line[256];
                    if(pth == pth->service->outdaemon)
                    {
                        sprintf(line, "/tmp/%s_outdaemon.log", pth->service->service_name);
                        evbase_set_logfile(pth->evbase, line);
                    }
                    else
                    {
                        sprintf(line, "/tmp/%s_indaemon.log", pth->service->service_name);
                        evbase_set_logfile(pth->evbase, line);
                    }
                }
            }
            do
            {
                i = pth->evbase->loop(pth->evbase, 0, NULL);
                if(pth->service->flag & SB_LOG_THREAD)
                {
                    if(pth == pth->service->outdaemon)
                    {
                        ACCESS_LOGGER(pth->logger, "outdaemon_loop(%d/%d) q[%p]{total:%d left:%d}", i, k, pth->message_queue, QMTOTAL(pth->message_queue), QNLEFT(pth->message_queue));
                    }
                    else
                    {
                        ACCESS_LOGGER(pth->logger, "iodaemon_loop(%d/%d) q[%p]{total:%d left:%d}", i, k, pth->message_queue, QMTOTAL(pth->message_queue), QNLEFT(pth->message_queue));
                    }
                }
                if(pth->message_queue && (k = QMTOTAL(pth->message_queue)) > 0)
                {
                    qmessage_handler(pth->message_queue, pth->logger);
                }
                if((pth->service->flag & (SB_IO_NANOSLEEP|SB_IO_USLEEP|SB_IO_SELECT)) 
                        && n++ > pth->service->nworking_tosleep)
                {
                    if(pth->service->flag & SB_IO_NANOSLEEP) nanosleep(&ts, NULL); 
                    else if(pth->service->flag & SB_IO_USLEEP) usleep(pth->usec_sleep);
                    else if(pth->service->flag & SB_IO_SELECT) select(0, NULL, NULL, NULL, &tv);
                    n = 0;
                }
            }while(pth->running_status);
            if(pth == pth->service->outdaemon)
            {
                ACCESS_LOGGER(pth->logger, "Ready for stop outdaemons[%p]", pth);
            }
            else
            {
                ACCESS_LOGGER(pth->logger, "Ready for stop iodaemons[%p]", pth);
            }
        }
        else if(pth->listenfd > 0)
        {
            do
            {
                service_accept_handler(pth->service);
            }while(pth->running_status);
            ACCESS_LOGGER(pth->logger, "Ready for stop threads[acceptor]");
        }
        else
        {
            if(pth->use_cond_wait)
            {
                do
                {
                    //DEBUG_LOGGER(pth->logger, "starting cond-wait() threads[%p]->qmessage[%p]_handler(%d)", (void *)pth->threadid,pth->message_queue, QMTOTAL(pth->message_queue));
                    if(pth->message_queue && (k = QMTOTAL(pth->message_queue)) > 0)
                    {
                        qmessage_handler(pth->message_queue, pth->logger);
                        i = 1;
                    }
                    if(QMTOTAL(pth->message_queue) < 1) 
                    {
                        if(pth->service->flag & SB_USE_EVSIG)
                            evsig_wait(&(pth->evsig));
                        else if(pth->service->flag & SB_USE_COND)
                        {
                            MUTEX_WAIT(pth->mutex);
                        }
                        else
                            nanosleep(&ts, NULL);
                    }
                }while(pth->running_status);
                ACCESS_LOGGER(pth->logger, "ready to exit threads/daemons[%d]", pth->index);
            }
            else
            {
                do
                {
                    //DEBUG_LOGGER(pth->logger, "starting threads[%p]->qmessage[%p]_handler(%d)", (void *)(pth->threadid),pth->message_queue, QMTOTAL(pth->message_queue));
                    if(pth->evtimer){EVTIMER_CHECK(pth->evtimer);}
                    if(pth->message_queue && QMTOTAL(pth->message_queue) > 0)
                    {
                        qmessage_handler(pth->message_queue, pth->logger);
                    }
                    nanosleep(&ts, NULL);
                    //WARN_LOGGER(pth->logger, "over threads[%p]->qmessage[%p]_handler(%d)", (void *)(pth->threadid),pth->message_queue, QMTOTAL(pth->message_queue));
                }while(pth->running_status);
                ACCESS_LOGGER(pth->logger, "ready to exit threads/daemons[%d]", pth->index);
            }
        }
        if(pth->message_queue && QMTOTAL(pth->message_queue) > 0)
            qmessage_handler(pth->message_queue, pth->logger);
        ACCESS_LOGGER(pth->logger, "terminate threads[%d][%p] evbase[%p] qmessage[%p] ioqmessage[%p] qtotal:%d", pth->index, (void *)(pth->threadid), pth->evbase, pth->message_queue, pth->inqmessage, QMTOTAL(pth->message_queue));
    }
#ifdef HAVE_PTHREAD
    pthread_exit(NULL);
#endif
    return ;
}
Example #10
0
BOOLEAN DelFileSaveList(PFILEINFOSET lpFileInfoSet)
{
  ULONG           dwSize, dwSizeOfItem;
  CHAR           *lpszStr;
  KDLinkedListItem* lpNode;
  PFILEINFO       lpFileInfo, lpFileInfoIn;

  if (!_MmIsAddressValid(pSaveList))
    return FALSE;
  if (!_MmIsAddressValid(pDirTree))
    return FALSE;
  if (!_MmIsAddressValid(lpFileInfoSet))
    return FALSE;
  if (lpFileInfoSet->dwSize < SIZEOF_FILEINFOSET)
    return FALSE;

  MUTEX_WAIT(LockMutexToFileSaveList);

  dwSize = lpFileInfoSet->dwSize - (SIZEOF_FILEINFOSET - SIZEOF_FILEINFO);
  lpFileInfoIn = &lpFileInfoSet->FileInfo[0];
  while (dwSize > SIZEOF_FILEINFO)
  {
    if (!CheckFileInfo(lpFileInfoIn))
      break;
    dwSizeOfItem = ((SIZEOF_FILEINFO-sizeof(CHAR)) + lpFileInfoIn->dwSizeAllNamesArea);
    if (lpFileInfoIn->dwSizeAnsiName > sizeof(CHAR))
    {
      lpNode = pSaveList->GetHead();
      while (_MmIsAddressValid(lpNode))
      {
        lpFileInfo = (PFILEINFO)lpNode->GetObject();
        if (!_MmIsAddressValid(lpFileInfo))
        {
          lpNode = lpNode->GetNext();
          continue;
        }

        lpszStr = lpFileInfoIn->szNames+lpFileInfoIn->dwOffsetToAnsiName;
        
        if (!CompareString(lpFileInfo->szNames+lpFileInfo->dwOffsetToAnsiName, lpszStr, TRUE))
        {
          DbgPrintSO(("He4HookInv: DelFileSaveList: Start delete - %s\n", lpszStr));
          pDirTree->Remove((PWSTR)(lpFileInfo->szNames+lpFileInfo->dwOffsetToUniName), NULL);
          pSaveList->Remove(lpNode);
          lpNode = pSaveList->GetHead();
          DbgPrintSO(("He4HookInv: DelFileSaveList: End delete - %s\n", lpszStr));
      
          FreePoolToKHeap(hKHeapSOFileList, lpFileInfo); 
          continue;
        }
        
        lpNode = lpNode->GetNext();
      }
    }
    dwSize -= dwSizeOfItem;
    lpFileInfoIn = (PFILEINFO)((PCHAR)lpFileInfoIn + dwSizeOfItem);
  }


  MUTEX_RELEASE(LockMutexToFileSaveList);

  return TRUE;
}
Example #11
0
BOOLEAN AddFileSaveList(PFILEINFOSET lpFileInfoSet)
{
  PFILEINFO       lpFileInfo, lpFileInfoIn;
  ULONG           dwSize, dwSizeOfItem, dwSizeOfItemNew;
  PWSTR           pwszNtFileName;
  ULONG           dwSizeOfNtFileName;
  ANSI_STRING     FileNameAnsi;
  UNICODE_STRING  FileNameUni;

  if (!_MmIsAddressValid(lpFileInfoSet))
    return FALSE;
  if (lpFileInfoSet->dwSize < SIZEOF_FILEINFOSET)
    return FALSE;

  MUTEX_WAIT(LockMutexToFileSaveList);

  DbgPrintSO(("He4HookInv: AddFileSaveList: Start!!!\n"));
  if (!_MmIsAddressValid(pSaveList))
  {
    pSaveList = new KDLinkedList(NULL);
    if (pSaveList == NULL)
    {
      DbgPrintSO(("He4HookInv: AddFileSaveList: File list create ERROR!!!\n"));
      MUTEX_RELEASE(LockMutexToFileSaveList);
      return FALSE;
    }
  }

  if (!_MmIsAddressValid(pDirTree))
  {
    pDirTree = new KShieldDirectoryTree();
    if (pDirTree == NULL)
    {
      DbgPrintSO(("He4HookInv: AddFileSaveList: KShieldDirectoryTree create ERROR!!!\n"));
      MUTEX_RELEASE(LockMutexToFileSaveList);
      return FALSE;
    }
  }

  DbgPrintSO(("He4HookInv: AddFileSaveList: List created OK!!!\n"));

  dwSize = lpFileInfoSet->dwSize - (SIZEOF_FILEINFOSET - SIZEOF_FILEINFO);
  lpFileInfoIn = &lpFileInfoSet->FileInfo[0];
  while(dwSize > SIZEOF_FILEINFO)
  {
    if (!CheckFileInfo(lpFileInfoIn))
      break;
    dwSizeOfItem = ((SIZEOF_FILEINFO-sizeof(CHAR)) + lpFileInfoIn->dwSizeAllNamesArea);
    if (lpFileInfoIn->dwSizeAnsiName > sizeof(CHAR))
    {
      pwszNtFileName = (PWSTR)_AllocatePoolFromKHeap(hKHeapSOFileList, sizeof(WCHAR)*lpFileInfoIn->dwSizeAnsiName+2048);
      if (pwszNtFileName)
      {
        RtlInitAnsiString(&FileNameAnsi, lpFileInfoIn->szNames+lpFileInfoIn->dwOffsetToAnsiName);
        RtlAnsiStringToUnicodeString(&FileNameUni, &FileNameAnsi, TRUE);
        dwSizeOfNtFileName = DosPathNameToNtPathName(FileNameUni.Buffer, pwszNtFileName, sizeof(WCHAR)*lpFileInfoIn->dwSizeAnsiName+2048, 255, NULL);
        RtlFreeUnicodeString(&FileNameUni);

        if (dwSizeOfNtFileName)
        {
          dwSizeOfNtFileName += sizeof(WCHAR);
          dwSizeOfItemNew = (SIZEOF_FILEINFO-sizeof(CHAR)) + lpFileInfoIn->dwSizeAnsiName + dwSizeOfNtFileName;
          
          #define ADD_NT_PATH   L"\\??\\"
          //L"\\DosDevices\\"
          //L"\\??\\"
          
          if (lpFileInfoIn->dwAccessType & FILE_ACC_TYPE_EXCHANGE)
          {
            if (lpFileInfoIn->dwSizeAnsiChangedName > sizeof(CHAR))
            {
              dwSizeOfItemNew += sizeof(WCHAR)*lpFileInfoIn->dwSizeAnsiChangedName + sizeof(ADD_NT_PATH)-sizeof(WCHAR);
            }
            else
            {
              if (lpFileInfoIn->dwSizeUniChangedName > sizeof(WCHAR))
                dwSizeOfItemNew += lpFileInfoIn->dwSizeUniChangedName;
            }
          }
          
          lpFileInfo = (PFILEINFO)_AllocatePoolFromKHeap(hKHeapSOFileList, dwSizeOfItemNew+sizeof(WCHAR));
          if (lpFileInfo)
          {
            memset(lpFileInfo, 0, dwSizeOfItemNew+sizeof(WCHAR));
            lpFileInfo->dwAccessType = lpFileInfoIn->dwAccessType;
            lpFileInfo->dwSizeAllNamesArea = dwSizeOfItemNew - (SIZEOF_FILEINFO-sizeof(CHAR));
          
            lpFileInfo->dwOffsetToAnsiName = 0;
            lpFileInfo->dwSizeAnsiName = lpFileInfoIn->dwSizeAnsiName;
          
            RtlCopyMemory(lpFileInfo->szNames+lpFileInfo->dwOffsetToAnsiName,
                          lpFileInfoIn->szNames+lpFileInfoIn->dwOffsetToAnsiName,
                          lpFileInfo->dwSizeAnsiName);
          
            lpFileInfo->dwOffsetToUniName = lpFileInfo->dwOffsetToAnsiName + lpFileInfo->dwSizeAnsiName;
            lpFileInfo->dwSizeUniName = dwSizeOfNtFileName;
          
            RtlCopyMemory(lpFileInfo->szNames+lpFileInfo->dwOffsetToUniName, pwszNtFileName, dwSizeOfNtFileName);
          
            if (lpFileInfoIn->dwAccessType & FILE_ACC_TYPE_EXCHANGE)
            {
              if (lpFileInfoIn->dwSizeAnsiChangedName > sizeof(CHAR))
              {
                lpFileInfo->dwOffsetToUniChangedName = lpFileInfo->dwOffsetToUniName + lpFileInfo->dwSizeUniName;
                lpFileInfo->dwSizeUniChangedName = sizeof(WCHAR)*lpFileInfoIn->dwSizeAnsiChangedName+sizeof(ADD_NT_PATH)-sizeof(WCHAR);
          
                RtlInitAnsiString(&FileNameAnsi, lpFileInfoIn->szNames+lpFileInfoIn->dwOffsetToAnsiChangedName);
                RtlAnsiStringToUnicodeString(&FileNameUni, &FileNameAnsi, TRUE);
          
                RtlCopyMemory(lpFileInfo->szNames+lpFileInfo->dwOffsetToUniChangedName, ADD_NT_PATH, sizeof(ADD_NT_PATH));
                RtlCopyMemory((lpFileInfo->szNames+lpFileInfo->dwOffsetToUniChangedName+sizeof(ADD_NT_PATH)-sizeof(WCHAR)), FileNameUni.Buffer,
                              (sizeof(WCHAR)*lpFileInfoIn->dwSizeAnsiChangedName) < (FileNameUni.Length+sizeof(WCHAR)) ? (sizeof(WCHAR)*lpFileInfoIn->dwSizeAnsiChangedName) : (FileNameUni.Length+sizeof(WCHAR)));
                RtlFreeUnicodeString(&FileNameUni);
              }
              else
              {
                if (lpFileInfoIn->dwSizeUniChangedName > sizeof(WCHAR))
                {
                  lpFileInfo->dwOffsetToUniChangedName = lpFileInfo->dwOffsetToUniName + lpFileInfo->dwSizeUniName;
                  lpFileInfo->dwSizeUniChangedName = lpFileInfoIn->dwSizeUniChangedName;
                
                  RtlCopyMemory(
                                lpFileInfo->szNames+lpFileInfo->dwOffsetToUniChangedName,
                                lpFileInfoIn->szNames+lpFileInfoIn->dwOffsetToUniChangedName,
                                lpFileInfo->dwSizeUniChangedName
                               );
                }
                else
                {
                  lpFileInfo->dwAccessType &= ~FILE_ACC_TYPE_EXCHANGE;
                }
              }
            }

            PVOID pContext;
            if (pDirTree->Find((PWSTR)(lpFileInfo->szNames+lpFileInfo->dwOffsetToUniName), &pContext) == NULL)
            {
              DbgPrintSO(("He4HookInv: AddFileSaveList: %s, type = %x\n", lpFileInfo->szNames+lpFileInfo->dwOffsetToAnsiName, lpFileInfo->dwAccessType));
              if (pDirTree->Add((PWSTR)(lpFileInfo->szNames+lpFileInfo->dwOffsetToUniName), (PVOID)lpFileInfo) == TRUE)
              {
                if (pSaveList->AddTailObject(lpFileInfo) == FALSE)
                {
                  pDirTree->Remove((PWSTR)(lpFileInfo->szNames+lpFileInfo->dwOffsetToUniName), NULL);
                  FreePoolToKHeap(hKHeapSOFileList, lpFileInfo); 
                }
              }
              else
              {
                FreePoolToKHeap(hKHeapSOFileList, lpFileInfo); 
              }
            }
            else
            {
              FreePoolToKHeap(hKHeapSOFileList, lpFileInfo); 
            }
          }
        }
        FreePoolToKHeap(hKHeapSOFileList, pwszNtFileName);
      }
    }
    dwSize -= dwSizeOfItem;
    lpFileInfoIn = (PFILEINFO)((PCHAR)lpFileInfoIn + dwSizeOfItem);
  }

  MUTEX_RELEASE(LockMutexToFileSaveList);

  return TRUE;
}