O que está acontecendo com esse ponto de nova análise criado pelo mklink?

O que está acontecendo com esse ponto de nova análise criado pelo mklink?

Aqui está um comportamento estranho mklinkque encontrei no Windows desde o Vista. Suspeito que possa haver um defeito mklinkou até mesmo tão profundo quanto o driver do sistema de arquivos NTFS, mas o comportamento precisa de alguma explicação. Esse comportamento foi encontrado no Windows 7 e 10, respectivamente.

Suponha que temos um diretório em um volume NTFS (façaNÃOtente isso em qualquer coisa, menos em um volume que você está criando para esse único propósito!) e em 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, eusaberisso ébobagem. Mas foi o resultado de um teste para saber se um fluxo de dados alternativo (ADS) poderia se tornar um ponto de nova análise. Acreditei que não, porque um fluxo de dados alternativo só tem um nome, um tamanho e - bem - os dados dentro dele. Ao contrário de um arquivo ou diretório, ele não possui atributos de arquivo ou carimbos de data/hora próprios e, portanto, não haveria nenhum atributo para designar o ADS como ponto de nova análise (o que de outra forma acontece através dos atributos do arquivo). Ou dito de outra forma: os pontos de nova análise só podem referir-separaentradas de diretório (via $Extend\$Reparse), enquanto ADS estão vinculados a entradas de 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 é novidade que a tentativa de mudar para este diretório não funciona e resultaThe 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. Apenas inspecionar os dados do ponto de nova análise me dá algo em que me agarrar:

 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 faço para me livrar desse ponto de nova análise novamente com ferramentas integradas do Windows (ou, na sua falta, 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 é bem-sucedido (presumivelmente via CreateFile()).
  2. mklinkdefine REPARSE_DATA_BUFFERo "arquivo" criado que não pode funcionar porque é um ADS em um diretório. Então, 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 consegue controlar um diretório sem especificar um sinalizador específico. Portanto, não apenas criamos mklinkum link simbólicoem um diretóriopara um arquivo, também evitamos a necessidade de especificar FILE_FLAG_BACKUP_SEMANTICS.

A documentação FILE_FLAG_BACKUP_SEMANTICSabaixoCreateFilelê:

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 obter mais informações, consulte a seção Comentários.


Para reproduzir eu recomendo fortemente que vocênãotente isso em uma unidade NTFS existente, mas em vez disso, crie uma nova usando oImDiskDriver de disco RAM 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 como achar melhor. -mindica uma letra de unidade e -so tamanho do disco RAM.)

informação relacionada