Exemple #1
0
/*
 * Class:     net_decasdev_dokan_Dokan
 * Method:    isNameInExpression
 * Signature: (Ljava/lang/String;Ljava/lang/String;Z)Z
 */
JNIEXPORT jboolean JNICALL Java_net_decasdev_dokan_Dokan_isNameInExpression
( JNIEnv* env, jclass, jstring jexpression, jstring jname, jboolean jignoreCase ) {
	try {
		const jchar* pExp = env->GetStringChars( jexpression, NULL );
		if ( pExp == NULL )
			throw "Failed at GetStringChars for expression";

		const jchar* pName = env->GetStringChars( jname, NULL );
		if ( pName == NULL )
			throw "Failed at GetStringChars for name";

		jboolean result = DokanIsNameInExpression( ( LPCWSTR )pExp, ( LPCWSTR )pName, jignoreCase );

		env->ReleaseStringChars( jexpression, pExp );
		env->ReleaseStringChars( jname, pName );

		return result;
	} catch ( const char* msg ) {
		env->ThrowNew( env->FindClass( "java/lang/IllegalArgumentException" ), msg );
		return FALSE;
	}
}
Exemple #2
0
// check whether Name matches Expression
// Expression can contain "?"(any one character) and "*" (any string)
// when IgnoreCase is TRUE, do case insenstive matching
//
// http://msdn.microsoft.com/en-us/library/ff546850(v=VS.85).aspx
// * (asterisk) Matches zero or more characters.
// ? (question mark) Matches a single character.
// DOS_DOT Matches either a period or zero characters beyond the name string.
// DOS_QM Matches any single character or, upon encountering a period or end
//        of name string, advances the expression to the end of the set of
//        contiguous DOS_QMs.
// DOS_STAR Matches zero or more characters until encountering and matching
//          the final . in the name.
BOOL DOKANAPI DokanIsNameInExpression(LPCWSTR Expression, // matching pattern
                                      LPCWSTR Name,       // file name
                                      BOOL IgnoreCase) {
  ULONG ei = 0;
  ULONG ni = 0;

  while (Expression[ei] != '\0') {

    if (Expression[ei] == L'*') {
      ei++;
      if (Expression[ei] == '\0')
        return TRUE;

      while (Name[ni] != '\0') {
        if (DokanIsNameInExpression(&Expression[ei], &Name[ni], IgnoreCase))
          return TRUE;
        ni++;
      }

    } else if (Expression[ei] == DOS_STAR) {

      ULONG p = ni;
      ULONG lastDot = 0;
      ei++;

      while (Name[p] != '\0') {
        if (Name[p] == L'.')
          lastDot = p;
        p++;
      }

      BOOL endReached = FALSE;
      while (!endReached) {

        endReached = (Name[ni] == '\0' || ni == lastDot);

        if (!endReached) {
          if (DokanIsNameInExpression(&Expression[ei], &Name[ni], IgnoreCase))
            return TRUE;

          ni++;
        }
      }

    } else if (Expression[ei] == DOS_QM) {

      ei++;
      if (Name[ni] != L'.') {
        ni++;
      } else {

        ULONG p = ni + 1;
        while (Name[p] != '\0') {
          if (Name[p] == L'.')
            break;
          p++;
        }

        if (Name[p] == L'.')
          ni++;
      }

    } else if (Expression[ei] == DOS_DOT) {
      ei++;

      if (Name[ni] == L'.')
        ni++;

    } else {
      if (Expression[ei] == L'?') {
        ei++;
        ni++;
      } else if (IgnoreCase && towupper(Expression[ei]) == towupper(Name[ni])) {
        ei++;
        ni++;
      } else if (!IgnoreCase && Expression[ei] == Name[ni]) {
        ei++;
        ni++;
      } else {
        return FALSE;
      }
    }
  }

  if (ei == wcslen(Expression) && ni == wcslen(Name))
    return TRUE;

  return FALSE;
}
Exemple #3
0
// add entry which matches the pattern specifed in EventContext
// to the buffer specifed in EventInfo
//
LONG MatchFiles(PEVENT_CONTEXT EventContext, PEVENT_INFORMATION EventInfo,
                PLIST_ENTRY FindDataList, BOOLEAN PatternCheck,
                PDOKAN_INSTANCE DokanInstance) {
  PLIST_ENTRY thisEntry, listHead, nextEntry;

  ULONG lengthRemaining = EventInfo->BufferLength;
  PVOID currentBuffer = EventInfo->Buffer;
  PVOID lastBuffer = currentBuffer;
  ULONG index = 0;

  PWCHAR pattern = NULL;

  // search patten is specified
  if (PatternCheck &&
      EventContext->Operation.Directory.SearchPatternLength != 0) {
    pattern = (PWCHAR)(
        (SIZE_T)&EventContext->Operation.Directory.SearchPatternBase[0] +
        (SIZE_T)EventContext->Operation.Directory.SearchPatternOffset);
  }

  listHead = FindDataList;

  for (thisEntry = listHead->Flink; thisEntry != listHead;
       thisEntry = nextEntry) {

    PDOKAN_FIND_DATA find;
    nextEntry = thisEntry->Flink;

    find = CONTAINING_RECORD(thisEntry, DOKAN_FIND_DATA, ListEntry);

    DbgPrintW(L"FileMatch? : %s (%s,%d,%d)\n", find->FindData.cFileName,
              (pattern ? pattern : L"null"),
              EventContext->Operation.Directory.FileIndex, index);

    // pattern is not specified or pattern match is ignore cases
    if (!pattern ||
        DokanIsNameInExpression(pattern, find->FindData.cFileName, TRUE)) {

      if (EventContext->Operation.Directory.FileIndex <= index) {
        // index+1 is very important, should use next entry index
        ULONG entrySize = DokanFillDirectoryInformation(
            EventContext->Operation.Directory.FileInformationClass,
            currentBuffer, &lengthRemaining, &find->FindData, index + 1,
            DokanInstance);
        // buffer is full
        if (entrySize == 0)
          break;

        // pointer of the current last entry
        lastBuffer = currentBuffer;

        // end if needs to return single entry
        if (EventContext->Flags & SL_RETURN_SINGLE_ENTRY) {
          DbgPrint("  =>return single entry\n");
          index++;
          break;
        }

        DbgPrint("  =>return\n");

        // the offset of next entry
        ((PFILE_BOTH_DIR_INFORMATION)currentBuffer)->NextEntryOffset =
            entrySize;

        // next buffer position
        currentBuffer = (PCHAR)currentBuffer + entrySize;
      }
      index++;
    }
  }

  // Since next of the last entry doesn't exist, clear next offset
  ((PFILE_BOTH_DIR_INFORMATION)lastBuffer)->NextEntryOffset = 0;

  // acctualy used length of buffer
  EventInfo->BufferLength =
      EventContext->Operation.Directory.BufferLength - lengthRemaining;

  if (index <= EventContext->Operation.Directory.FileIndex) {

    if (thisEntry != listHead)
      return -2; // BUFFER_OVERFLOW

    return -1; // NO_MORE_FILES
  }

  return index;
}