Como criar um pipe anônimo que fornece acesso a todos

IMPORTANTE: Este artigo foi traduzido por um sistema de tradução automática (também designado por Machine Translation ou MT), não tendo sido portanto traduzido ou revisto por pessoas. A Microsoft possui artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais, com o objetivo de oferecer em português a totalidade dos artigos existentes na base de dados de suporte. No entanto, a tradução automática não é sempre perfeita, podendo conter erros de vocabulário, sintaxe ou gramática. A Microsoft não é responsável por incoerências, erros ou prejuízos ocorridos em decorrência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza atualizações freqüentes ao software de tradução automática (MT). Obrigado.

Clique aqui para ver a versão em Inglês deste artigo: 813414
Sumário
Este artigo descreve como criar um pipe anônimo que fornece acesso a todos. Este artigo contém um aplicativo de exemplo que cria um pipe de sessão anônima é usado para comunicação entre o servidor e o cliente. Este artigo descreve o seguinte em detalhes:
  • Criando um servidor que grava as informações em uma extremidade do pipe.
  • registrar o nome do pipe no registro.
  • tratamento de segurança do Windows ao comunicar-se sobre o pipe.
  • criar um cliente que lê as informações de outro extremo do pipe.
INTRODUÇÃO
Este artigo descreve como criar um servidor de pipe que envia e recebe dados entre domínios sem exigir que nomes de usuário e senhas. Quando um cliente se conecta ao servidor de pipe, o servidor faz um acesso verificar, e em seguida, solicita o cliente autentique. Dependendo de como as permissões do pipe são definidas, o acesso pode ser concedido ou negado. Se o usuário cliente tiver um token de acesso, o cliente pode se conectar ao servidor. Se o cliente não tiver um token de acesso, o aplicativo cliente deve executar um logon para o servidor. No entanto, às vezes, talvez seja necessário conceder acesso a todos. Portanto, você deve criar um pipe anônimo ou nulo, sessão. Porque você está concedendo permissões a todos, o pipe não deve conceder acesso a informações adequadas para os usuários.
Mais Informações
O aplicativo de exemplo neste artigo é um aplicativo cliente/servidor simples que usa um pipe nomeado anônimo. O servidor grava incrementalmente números para o pipe que são lidos e impresso pelo cliente. Como o pipe é anônimo, o cliente pode se conectar de outros domínios através de um logon anônimo. O aplicativo de exemplo é explicado da seguinte maneira.

Servidor

O servidor cria pipes anônimos e em seguida, escuta clientes de. Para criar um pipe anônimo, certifique-se de que você faça o seguinte:
  1. Adicione o nome do pipe ao registro.
  2. Defina os atributos LPSECURITY_ATTRIBUTES que são passados para a função de CreateNamedPipe .

Registro

No registro do computador servidor, o nome do pipe é adicionado à seguinte subchave do Registro:
\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters\
O nome do pipe que é adicionado a essa entrada do registro é o nome após o último caractere barra invertida (\) na seqüência que é usado para abrir o pipe.

Por exemplo, para o \\ myserver \pipe\AnonymousPipe pipe, você deve adicionar AnonymousPipe à entrada do Registro NullSessionPipes no computador servidor. Você pode fazer isso usando a função RegisterNullSession e a função UnregisterNullSession no aplicativo de exemplo.

Observação myserver é um espaço reservado para o nome do seu servidor.

Segurança

Muitos programadores use NULL Discretionary Access controle DACL (lista) para fornecer acesso anônimo a recursos compartilhados. No entanto, não existem restrições que são definidas para acessar o recurso compartilhado. Você deve criar um identificador de segurança (SID) que fornece o logon anônimo e o acesso somente leitura para o pipe. O SID que você criar o exemplo é conhecido por cada instalação do Microsoft Windows e é denominado AnonymousLogin. Esse SID é descrito como S-1-5-7. Para obter mais informações sobre esses números, consulte o arquivo Winnt.h. Quando o cliente pipe se conecta ao servidor, um logon anônimo é executado fazendo uma chamada para a função WNetAddConnection2 e o SID AnonymousLogin irá conceder o acesso. No aplicativo de exemplo, uma pequena classe é denominada SEC é criada para lidar com as estruturas de acesso complexos. Esse comportamento facilita a liberação de memória alocada. A função BuildSecurityAttributes nessa classe cria o SID e define as permissões. As permissões para o logon anônimo são definidas como somente leitura porque o pipe é um pipe de somente leitura. Para fazer isso, fazer uma chamada para a função AddAccessAllowedAce . Se você deseja criar um pipe tem de leitura e permissões de gravação, você deve alterar as permissões com a função AddAccessAllowedAce .

O outro SID deve ser definido pelo proprietário que possui o pipe nomeado, e isso garante que o aplicativo tem acesso ao pipe nomeado. O SID do proprietário é o SID de usuário que está executando o thread ou o processo de. A função GetUserSid extrai o SID do token do usuário. O token é criado quando você faz logon e você especificar o nome e senha que é usada para todas as verificações de acesso.

Com os atributos definidos, o servidor chama a função de CreateNamedPipe e, em seguida, aguarda chamadas de cliente.

Cliente

O cliente abre o pipe com uma chamada para a função CreateFile . Se ocorrer um erro, o cliente verifica que se é um erro de falha de logon, um acesso negado erro ou um erro de senha incorreta. Se ocorrer um erro, execute um logon anônimo chamando a função WNetAddConnection2 e passando uma seqüência vazia como nome de usuário e senha. Quando a sessão nula é estabelecida, o cliente chama a função CreateFile novamente. Depois que o cliente é conectado, ele imprime um número cada segundo.

Aplicativo de exemplo

Para criar um aplicativo que se comunica entre os processos, usando um pipe anônimo que fornece acesso a todos, execute essas etapas:
  1. Inicie o Microsoft Visual C++ 6.0.
  2. No menu arquivo , clique em novo .
  3. Na guia projetos , clique em Aplicativo de console do Win32 , digite MyApp na caixa nome do projeto e, em seguida, clique em OK .
  4. Na caixa de diálogo Win32 Console Application - etapa 1 de 1 , clique em Concluir .
  5. Na janela de Informações sobre o novo projeto , clique em OK .
  6. No menu arquivo , clique em novo . A caixa de diálogo novo será exibida.
  7. Clique em arquivo de origem C++ . No painel à direita, digite MyApp na caixa nome do arquivo e, em seguida, clique em OK .
  8. No painel esquerdo, clique na guia FileView .
  9. Expanda MyApp arquivos e, em seguida, expanda Arquivos de origem .
  10. Em Arquivos de origem , clique com o botão direito do mouse MyApp.cpp e, em seguida, clique em Abrir . No painel à direita, a exibição de código do arquivo MyApp.cpp abre.
  11. Add the following code to the MyApp.cpp file:
    #define UNICODE#include    <windows.h>#include    <stdio.h>// Typesclass SEC{    // Class to handle security attributespublic:    SEC();    ~SEC();    BOOL BuildSecurityAttributes( SECURITY_ATTRIBUTES* psa );    private:    BOOL GetUserSid( PSID*  ppSidUser );    BOOL    allocated;    PSECURITY_DESCRIPTOR    psd;    PACL    pACL;    PTOKEN_USER pTokenUser;};// Constantsstatic const WCHAR* PipeName = L"AnonymousPipe";// Functionsstatic void Client( const WCHAR* server );static void Server( void );static void WriteToPipe( HANDLE hPipe );static void ReadFromPipe( HANDLE hPipe );static void DisplayError( WCHAR *pszAPI);static BOOL WINAPI ConsoleCtrlHandler( DWORD CtrlType );static BOOL EstablishNullSession( const WCHAR* computerName );static BOOL RegisterNullSession( const WCHAR* pipeName );static BOOL UnregisterNullSession( const WCHAR* pipeName );static LONG RegInsertToMultiString( HKEY hKey, const WCHAR* valueName, const WCHAR* str );static LONG RegRemoveFromMultiString( HKEY hKey, const WCHAR* valueName, const WCHAR* str );static BOOL FindEntryInMultiString( const WCHAR* data, const WCHAR* entry, DWORD* offset );    void     wmain( int argc, WCHAR* argv[] ){    if( argc < 2 )     {        wprintf( L"Usage: pipe.exe <server|client [server name for client]>\n" );         exit(1);    }    if( !SetConsoleCtrlHandler( ConsoleCtrlHandler, TRUE ) )        DisplayError( L"SetConsoleCtrlHandler" );    if( wcsicmp( argv[1], L"client") == 0 )    {        WCHAR    server[512];        if( argc == 3 )        {            wcscpy( server, argv[2] );        }        else        {            wcscpy( server, L"." );        }        Client( server );    }    else    if( wcsicmp( argv[1], L"server" ) == 0 )    {        Server();    }    else     {        wprintf( L"Usage: pipe.exe <server|client [server name for client]>\n" );         exit(1);    }}//Runs the server void    Server( void ){    SEC sec;    HANDLE  hPipe;    BOOL    isConnected;    SECURITY_ATTRIBUTES     sa;    WCHAR   server[512];    swprintf( server, L"\\\\.\\pipe\\%s", PipeName );    if( !RegisterNullSession( PipeName ) )    {        wprintf( L"WARNING: could not register %s for Null Session, server will not be accessible from outside domain.\n", server );        wprintf( L"WARNING: only administrators can register a Null Session Pipe.\n" );    }    sec.BuildSecurityAttributes( &sa );    wprintf( L"INFORM: to stop, press Ctrl-C or Ctrl-Break.\n" );    while( 1 )    {        hPipe = CreateNamedPipe(                     server,                    PIPE_ACCESS_OUTBOUND,       // read-only pipe                    PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,                    PIPE_UNLIMITED_INSTANCES,                     sizeof(DWORD),                     0,                     NMPWAIT_USE_DEFAULT_WAIT,                             &sa );                            if( hPipe == INVALID_HANDLE_VALUE )               DisplayError( L"CreatePipe" );          // Wait for the client to connect.         wprintf( L"INFORM: listening at %s, waiting for client to connect\n", server );        isConnected = ConnectNamedPipe( hPipe, NULL ) ? TRUE : (GetLastError() == ERROR_PIPE_CONNECTED);         if( isConnected )         {            wprintf( L"INFORM: client connected.\n" );            WriteToPipe( hPipe );        }        else            // The client could not connect. Therefore, close the pipe.            CloseHandle(hPipe);              }}//Runs the clientvoid    Client( const WCHAR* server ){    HANDLE hPipe;    WCHAR fullName[512];    BOOL   triedLogon = FALSE;    swprintf( fullName, L"\\\\%s\\pipe\\%s", server, PipeName );    wprintf( L"INFORM: connecting to %s\n", fullName );    while( 1 )     {         hPipe = CreateFile(                     fullName,                    GENERIC_READ,                    FILE_SHARE_READ,                    NULL,                    OPEN_EXISTING,                    SECURITY_ANONYMOUS,                    NULL);         if( hPipe == INVALID_HANDLE_VALUE )        {            DWORD lastError = GetLastError();            // An error ocurred, try to analyse it                    if( (lastError == ERROR_LOGON_FAILURE) ||                (lastError == ERROR_ACCESS_DENIED) ||                (lastError == ERROR_INVALID_PASSWORD))  //Add other access errors here if it is required            {                if( triedLogon )                {                    DisplayError( L"CreateFile" );                }                else                if( EstablishNullSession( server ) )                {                    wprintf( L"INFORM: established Null session.\n" );                }                else                {                    wprintf( L"WARNING: could not establish Null Session.\n" );                }                triedLogon = TRUE;            }            else            if( lastError == ERROR_PIPE_BUSY )             {                // All pipe instances are busy. Therefore, wait for 20 seconds.                 wprintf( L"INFORM: pipe busy, trying for 20secs to reconnect.\n" );                if( !WaitNamedPipe( fullName, 20000) )                     DisplayError( L"WaitNamedPipe" );            }            else            {                DisplayError( L"CreateFile" );             }        }        else        {            ReadFromPipe( hPipe );        }    } }/**Tries to establish a NULL session to the remote computer. A NULL session allows access to NullSessionPipes ofthe server.Input parameters: computerName: name of the server to connect toOutput parameters: TRUE | FALSE*/ BOOL    EstablishNullSession( const WCHAR* computerName ){    NETRESOURCE nr;    WCHAR server[MAX_PATH];    DWORD ret;    if( wcscmp( computerName, L"." ) == 0 )    {        wcscpy( server, computerName );    }    else    {        wcscpy( server, L"\\\\" );        wcscat( server, computerName );    }        ZeroMemory( &nr, sizeof(nr) );    nr.dwType       = RESOURCETYPE_ANY;    nr.lpRemoteName = server;    ret = WNetAddConnection2( &nr, L"", L"", 0);    if( ret != ERROR_SUCCESS )    {        DisplayError( L"WNetAddConnection2" );        return FALSE;    }            return TRUE;}//Called when the user presses Ctrl-C or Ctrl-Break in the console window.BOOL WINAPI    ConsoleCtrlHandler( DWORD CtrlType ){    // clean up the registry    UnregisterNullSession( PipeName );    return FALSE;}/** Writes to the pipeInput parameters: hPipe: handle to an opened pipe*/ void    WriteToPipe( HANDLE hPipe ){    DWORD i = 0;    DWORD cbWrite, cbWritten;    cbWrite = sizeof(DWORD);    while( 1 )     {          if( !WriteFile( hPipe, &i, cbWrite,  &cbWritten,  NULL) )         {             if( cbWrite != cbWritten) break;          }         i++;         Sleep( 1000 );    }    // Flush the pipe to allow the client to read the contents of the pipe     // before disconnecting. Disconnect the pipe, and then close the     // handle to this pipe instance.      FlushFileBuffers( hPipe );     DisconnectNamedPipe( hPipe );     CloseHandle( hPipe );    wprintf( L"INFORM: client disconnected.\n" );}/** Reads from pipeInput parameters: hPipe: handle to opened pipe. */ void     ReadFromPipe( HANDLE hPipe ){    DWORD i, cbRead;    while( 1 )     {         if( !ReadFile( hPipe, &i, sizeof(DWORD), &cbRead, NULL) )        {            if( GetLastError() != ERROR_MORE_DATA )             {                CloseHandle( hPipe );                 DisplayError( L"ReadFile" );            }        }        wprintf( L" %li ", i );     };}/** Displays an error and exits the processInput parameters: pszAPI: name of the Win32 function that returned an error. */ void     DisplayError( WCHAR* pszAPI ){	LPVOID lpvMessageBuffer;	FormatMessage(  FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,                    NULL, GetLastError(),                     MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),                    (LPTSTR)&lpvMessageBuffer, 0, NULL);	//... now display this string	wprintf( L"ERROR: API        = %s.\n", pszAPI);	wprintf( L"       error code = %d.\n", GetLastError());	wprintf( L"       message    = %s.\n", (char *)lpvMessageBuffer);	// Free the buffer allocated by the system	LocalFree( lpvMessageBuffer );	ExitProcess( GetLastError() );}/**  Constructor */ SEC::    SEC() {     allocated = FALSE;     psd = NULL;     pACL = NULL;     pTokenUser = NULL; }/** Destructor */ SEC::    ~SEC(){     if( allocated )    {             if( psd ) HeapFree( GetProcessHeap(), 0, psd );        if( pACL ) HeapFree( GetProcessHeap(), 0 , pACL );        if( pTokenUser ) HeapFree( GetProcessHeap(), 0, pTokenUser );        allocated = FALSE;    }}/** Builds security attributes that allows read-only access to everyoneInput parameters: psa: security attributes to buildOutput parameters: TRUE | FALSE */ BOOL SEC::    BuildSecurityAttributes( SECURITY_ATTRIBUTES* psa ){    DWORD dwAclSize;    PSID  pSidAnonymous = NULL; // Well-known AnonymousLogin SID    PSID  pSidOwner = NULL;        if( allocated ) return FALSE;    SID_IDENTIFIER_AUTHORITY siaAnonymous = SECURITY_NT_AUTHORITY;    SID_IDENTIFIER_AUTHORITY siaOwner = SECURITY_NT_AUTHORITY;        do    {        psd = (PSECURITY_DESCRIPTOR) HeapAlloc( GetProcessHeap(),                                                HEAP_ZERO_MEMORY,                                                SECURITY_DESCRIPTOR_MIN_LENGTH);        if( psd == NULL )         {            DisplayError( L"HeapAlloc" );            break;        }        if( !InitializeSecurityDescriptor( psd, SECURITY_DESCRIPTOR_REVISION) )        {            DisplayError( L"InitializeSecurityDescriptor" );            break;        }        // Build anonymous SID        AllocateAndInitializeSid( &siaAnonymous, 1,                                   SECURITY_ANONYMOUS_LOGON_RID,                                   0,0,0,0,0,0,0,                                  &pSidAnonymous                                );        if( !GetUserSid( &pSidOwner ) )        {            return FALSE;        }        // Compute size of ACL        dwAclSize = sizeof(ACL) +                    2 * ( sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) ) +                    GetLengthSid( pSidAnonymous ) +                    GetLengthSid( pSidOwner );              pACL = (PACL)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwAclSize );        if( pACL == NULL )         {            DisplayError( L"HeapAlloc" );            break;        }           InitializeAcl( pACL, dwAclSize, ACL_REVISION);                   if( !AddAccessAllowedAce( pACL,                                  ACL_REVISION,                                  GENERIC_ALL,                                  pSidOwner                                ))         {            DisplayError( L"AddAccessAllowedAce" );            break;        }                        if( !AddAccessAllowedAce( pACL,                                  ACL_REVISION,                                  FILE_GENERIC_READ, //GENERIC_READ | GENERIC_WRITE,                                  pSidAnonymous                                ) )         {            DisplayError( L"AddAccessAllowedAce" );            break;        }           if( !SetSecurityDescriptorDacl( psd, TRUE, pACL, FALSE) )        {            DisplayError( L"SetSecurityDescriptorDacl" );            break;        }              psa->nLength = sizeof(SECURITY_ATTRIBUTES);        psa->bInheritHandle = TRUE;        psa->lpSecurityDescriptor = psd;        allocated = TRUE;    }while(0);    if( pSidAnonymous )   FreeSid( pSidAnonymous );    if( pSidOwner )       FreeSid( pSidOwner );        if( !allocated )    {        if( psd ) HeapFree( GetProcessHeap(), 0, psd );        if( pACL ) HeapFree( GetProcessHeap(), 0 , pACL );    }    return allocated;}/** Obtains the SID of the user running this thread or process.Output parameters: ppSidUser: the SID of the current user,TRUE   | FALSE: could not obtain the user SID */ BOOL SEC::    GetUserSid( PSID*  ppSidUser ){    HANDLE      hToken;    DWORD       dwLength;    DWORD       cbName = 250;    DWORD       cbDomainName = 250;        if( !OpenThreadToken( GetCurrentThread(), TOKEN_QUERY, TRUE, &hToken) )    {        if( GetLastError() == ERROR_NO_TOKEN )        {            if( !OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY, &hToken) )            {                return FALSE;            }        }        else        {            return FALSE;        }    }    if( !GetTokenInformation( hToken,       // handle of the access token                              TokenUser,    // type of information to retrieve                              pTokenUser,   // address of retrieved information                               0,            // size of the information buffer                              &dwLength     // address of required buffer size                              ))    {        if( GetLastError() == ERROR_INSUFFICIENT_BUFFER )        {            pTokenUser = (PTOKEN_USER) HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwLength );            if( pTokenUser == NULL )            {                return FALSE;            }        }        else        {            return FALSE;        }    }    if( !GetTokenInformation(   hToken,     // handle of the access token                                TokenUser,  // type of information to retrieve                                pTokenUser, // address of retrieved information                                 dwLength,   // size of the information buffer                                &dwLength   // address of required buffer size                                ))    {        HeapFree( GetProcessHeap(), 0, pTokenUser );        pTokenUser = NULL;        return FALSE;    }    *ppSidUser = pTokenUser->User.Sid;    return TRUE;}/** Registers a pipe as a NULL SESSION pipe that may be accessed by unauthenticated users.Input parameters: serverName: pipe to registerOutput parameters: TRUE: pipe registered   | FALSE: could no register pipe. */ BOOL            RegisterNullSession( const WCHAR* pipeName ){    LONG status;     HKEY hKey;    // Opens key    status = RegCreateKeyEx( HKEY_LOCAL_MACHINE,                              L"SYSTEM\\CurrentControlSet\\Services\\lanmanserver\\parameters",                              0,                              NULL,                              REG_OPTION_NON_VOLATILE,                              KEY_QUERY_VALUE | KEY_SET_VALUE,                              NULL,                              &hKey,                              NULL);    if( status != ERROR_SUCCESS )    {        return FALSE;    }    status = RegInsertToMultiString( hKey, L"NullSessionPipes", pipeName );    RegCloseKey( hKey );    if( status != ERROR_SUCCESS )    {        return FALSE;    }    return TRUE;}/** Unregisters a pipe from the NULL SESSION pipe list.Input parameters: pipeName: pipe to unregisterOutput parameters: TRUE: pipe unregistered or pipe was not registered  | FALSE: could not unregister pipe*/ BOOL            UnregisterNullSession( const WCHAR* pipeName ){    LONG status;     HKEY hKey;    // Opens key    status = RegCreateKeyEx( HKEY_LOCAL_MACHINE,                              L"SYSTEM\\CurrentControlSet\\Services\\lanmanserver\\parameters",                              0,                              NULL,                              REG_OPTION_NON_VOLATILE,                              KEY_QUERY_VALUE | KEY_SET_VALUE,                              NULL,                              &hKey,                              NULL);    if( status != ERROR_SUCCESS )    {        return FALSE;    }        status = RegRemoveFromMultiString( hKey, L"NullSessionPipes", pipeName );        RegCloseKey( hKey );    if( (status != ERROR_SUCCESS) && (status != ERROR_INVALID_NAME) )    {        return FALSE;    }    return TRUE;}/** Inserts a string to a MULTI_SZ value. If the string is already present, nothing will be added. Thisavoids duplicated strings.Input parameters: hKey: handle to open key, valueName: name of the multistring value to which the str value will be appended, str: string to append<-- ERROR_SUCCESS   | any error code returned by RegQueryValueEx and RegSetValueEx */ LONG    RegInsertToMultiString( HKEY hKey, const WCHAR* valueName, const WCHAR* str ){    LONG status;     BYTE* data;    DWORD newSize, oldSize, strSize;    // Obtains the current data size    status = RegQueryValueEx( hKey,                               valueName,                               NULL,                               NULL,                               NULL,                               &oldSize );    if( status != ERROR_SUCCESS )    {        return status;    }    // Allocates memory to hold all the data    strSize = (wcslen(str) + 1) * sizeof(WCHAR);    newSize = oldSize + strSize;    data = (BYTE*)HeapAlloc( GetProcessHeap(), 0 , newSize );    if( data == NULL )    {        return ERROR_OUTOFMEMORY;    }    // Obtains the current data    status = RegQueryValueEx( hKey,                               valueName,                               NULL,                               NULL,                               data,                               &oldSize );    if( status != ERROR_SUCCESS )    {        HeapFree( GetProcessHeap(), 0 , data );        return status;    }    // Looks if the data is already there    if( FindEntryInMultiString( (WCHAR*)data, str, NULL ) )    {        HeapFree( GetProcessHeap(), 0 , data );        return ERROR_SUCCESS;    }            // Appends our entry    CopyMemory( data+oldSize-2, str, strSize );    // Append another NULL terminator    data[newSize-2] = 0;    data[newSize-1] = 0;    // Sets the new data    status = RegSetValueEx( hKey,                             valueName,                             0,                             REG_MULTI_SZ,                             data,                             newSize );    HeapFree( GetProcessHeap(), 0 , data );    return status;}/** Removes a string from a MULTI_SZ value.Input parameters: hKey: handle to open key,valueName: name of the multistring value to which the str value will be appended,str: string to append<-- ERROR_SUCCESS   | ERROR_INVALID_NAME: str was not found   | any error code returned by RegQueryValueEx and RegSetValueEx */ LONG    RegRemoveFromMultiString( HKEY hKey, const WCHAR* valueName, const WCHAR* str ){    LONG status;     BYTE* data;    DWORD size, offset, strSize;    BYTE* p;    BOOL  found = FALSE;    // Obtains the current data size    status = RegQueryValueEx( hKey,                               valueName,                               NULL,                               NULL,                               NULL,                               &size );    if( status != ERROR_SUCCESS )    {        return status;    }    // Allocates memory to hold all the data    strSize = (wcslen(str) + 1) * sizeof(WCHAR);    data = (BYTE*)HeapAlloc( GetProcessHeap(), 0 , size );    if( data == NULL )    {        return ERROR_OUTOFMEMORY;    }    // Obtains the current data    status = RegQueryValueEx( hKey,                               valueName,                               NULL,                               NULL,                               data,                               &size );    if( status != ERROR_SUCCESS )    {        HeapFree( GetProcessHeap(), 0 , data );        return status;    }    // Searches the entry to be removed    found = FindEntryInMultiString( (WCHAR*)data, str, &offset );    if( !found )    {        HeapFree( GetProcessHeap(), 0 , data );        return ERROR_INVALID_NAME;    }    // Writes over the entry, and then puts it back in the registry    p = data + offset;    CopyMemory( p, p + strSize, size - strSize - offset );    status = RegSetValueEx( hKey,                             valueName,                             0,                             REG_MULTI_SZ,                             data,                             size - strSize );    HeapFree( GetProcessHeap(), 0 , data );    return status;}/** Input parameters: data: multi string in which the entry is to be found,entry: to findoffset: if not NULL holds the number of bytes from the beginning of data where entry startsOutput parameters: TRUE: found entry  | FALSE: did not find entry */ BOOL    FindEntryInMultiString( const WCHAR* data, const WCHAR* entry, DWORD* offset ){    BYTE* p;    DWORD read, tmp;    BOOL  found = FALSE;    p = (BYTE*)data;    read = 0;    while( !( (*p == 0 ) && ((*(p+1)) == 0 ) )  )    {        if( wcscmp( (WCHAR*)p, entry ) == 0 )        {            found = TRUE;            break;        }        tmp = (wcslen( (WCHAR*)p ) + 1) * sizeof(WCHAR);        read += tmp ;        p += tmp;    }    if( offset )    {        if( found )        {            *offset = read;        }        else        {            *offset = 0;        }    }    return found;}
  12. Para criar o aplicativo, você deve adicionar o arquivo Mpr.lib para seu projeto. Para fazer isso, execute as seguintes etapas:
    1. No menu Project , clique em configurações . A caixa de diálogo Configurações do projeto aparece.
    2. Clique na guia conexão e depois acrescente Mpr.lib para a seqüência na caixa biblioteca de objetos/módulos .
    3. Clique em OK .
  13. No menu Build , clique em Criar MyApp.exe .
  14. Para executar o aplicativo, execute essas etapas:
    1. Clique em Iniciar , clique em Executar , digite cmd na caixa Abrir e, em seguida, clique em OK .
    2. No prompt de comando, execute o seguinte comando:
      Path of MyApp \MyAPP servidor
      O servidor aguarda o cliente se conecte.

      Observação Path of MyApp é um espaço reservado para o caminho onde o arquivo MyApp.exe é salvo.
    3. Repita a etapa um, e execute o seguinte comando no prompt de comando:
      Path of MyApp \MyAPP cliente Computer_Name
      O cliente se conecta ao servidor e, em seguida, imprime os números em seqüência que são lidos do pipe.

      Observação Computer_Name é um espaço reservado para o nome do computador cliente.
Referências
Para obter mais informações, visite os seguintes sites da Microsoft Developer Network (MSDN):
Direitos de acesso e segurança de pipe anônimo
http://msdn2.microsoft.com/en-us/library/aa365142.aspx
credenciais de autenticação de logon do pipe anônimo sessão nula domínio acessar

Propriedades

ID do Artigo: 813414 - Última Revisão: 01/10/2007 06:28:35 - Revisão: 2.0

Microsoft Platform Software Development Kit-January 2000 Edition

  • kbmt kbclient kbserver kbpipes kbsecurity kbhowto KB813414 KbMtpt
Comentários