Aqui está um comportamento estranho que encontrei com o mklinkWindows desde o Vista. Suspeito que possa haver um defeito mklinkou mesmo a profundidade do driver do sistema de arquivos NTFS, mas o comportamento pode usar alguma explicação. Esse comportamento foi encontrado no Windows 7 e 10, respectivamente.

Suponha que tenhamos um diretório em um volume NTFS ( NÃO tente isso em nada além do volume que você está criando para esse único propósito!) E um arquivo nomeado bar.txtdentro dele.

md F:\1
echo foo > F:\1\bar.txt

Agora, emita o seguinte comando (via prompt privilegiado):

mklink F:\1:bar F:\1\bar.txt

... o que deve lhe dar:

symbolic link created for F:\1:bar <<===>> F:\1\bar.txt

Não se preocupe, eu sei que isso é bobagem . Mas foi o resultado de um teste se um fluxo de dados alternativo (ADS) poderia se tornar um ponto de nova análise. Afirmei que não podia, porque um fluxo de dados alternativo só tem um nome, um tamanho e - bem - os dados dentro dele. Diferentemente de um arquivo ou diretório, ele não possui atributos de arquivo ou carimbos de data / hora e, portanto, não haveria nenhum atributo para designar o ADS como ponto de nova análise (o que de outra forma ocorre através dos atributos do arquivo). Ou de forma diferente: os pontos de nova análise podem se referir apenas às entradas do diretório (via $Extend\$Reparse), enquanto o ADS está vinculado às entradas do diretório.

O resultado do comando acima é este:

F:\>dir /r
 Volume in drive F is TEST
 Volume Serial Number is 24F3-8A7D

 Directory of F:\

2018-04-03  20:47    <SYMLINKD>     1 [F:\1\bar.txt]
                                  0 1:bar:$DATA
               0 File(s)              0 bytes
               1 Dir(s)   4,244,283,392 bytes free

Não é de surpreender que tentar mudar para este diretório não funcione e produz The directory name is invalid.

Da mesma forma, a tentativa de excluir o ponto de nova análise usando junction -d(do Sysinternals Suite) ou usando fsutil reparsepoint deletefalha com o mesmo erro. Somente a inspeção dos dados do ponto de nova análise me dá algo a que me apegar:

 F:\>fsutil reparsepoint query F:\1
Reparse Tag Value : 0xa000000c
Tag value: Microsoft
Tag value: Name Surrogate
Tag value: Symbolic Link

Reparse Data Length: 0x00000044
Reparse Data:
0000:  18 00 20 00 00 00 18 00  00 00 00 00 46 00 3a 00  .. .........F.:.
0010:  5c 00 31 00 5c 00 62 00  61 00 72 00 2e 00 74 00  \.1.\.b.a.r...t.
0020:  78 00 74 00 5c 00 3f 00  3f 00 5c 00 46 00 3a 00  x.t.\.?.?.\.F.:.
0030:  5c 00 31 00 5c 00 62 00  61 00 72 00 2e 00 74 00  \.1.\.b.a.r...t.
0040:  78 00 74 00                                       x.t.

Agora, minha pergunta é o que aconteceu aqui e como me livrar de tal ponto de nova análise novamente com as ferramentas do Windows integradas (ou, na sua falta, com as externas)? Pontos de bônus por poder responder o que aconteceu com o arquivo dentro da pasta 1e divulgar sua metodologia.

Minha teoria de trabalho até agora é a seguinte:

  1. mklinkcria o "arquivo" F:\1:bare obtém êxito (presumivelmente via CreateFile()).
  2. mklinkdefine o REPARSE_DATA_BUFFER"arquivo" criado que não pode funcionar, pois é um ADS em um diretório. Portanto, internamente, o que acontece é que o driver do sistema de arquivos define o buffer de dados de nova análise no diretório

O resultado é o que vemos. O que me incomoda aqui é que normalmente você não pode obter um identificador em um diretório sem especificar um sinalizador específico. Portanto, não apenas mklinkcriamos um link simbólico em um diretório para um arquivo, mas também evitamos a necessidade de especificar FILE_FLAG_BACKUP_SEMANTICS.

A documentação de FILE_FLAG_BACKUP_SEMANTICSsob CreateFilelê:

Você deve definir esse sinalizador para obter um identificador para um diretório. Um identificador de diretório pode ser passado para algumas funções em vez de um identificador de arquivo. Para mais informações, consulte a seção Comentários.


Para reproduzir, recomendo que você não tente fazer isso em uma unidade NTFS existente, mas crie um novo usando o driver de disco RAM do ImDisk e a imdiskferramenta de linha de comando que o acompanha (via prompt privilegiado):

imdisk -a -t vm -p "/fs:ntfs /q /y /v:TEST" -s 4G -m F:

(altere os parâmetros da forma que achar melhor. -mindica uma letra de unidade e -so tamanho do disco RAM.)

0xC0000022L
fonte