Accueil > > > LISTER LES USERS ET LES PERMISSIONS DES DOSSIERS PARTAGÉS D'UN ORDI RÉSEAU (OU PAS : ))
LISTER LES USERS ET LES PERMISSIONS DES DOSSIERS PARTAGÉS D'UN ORDI RÉSEAU (OU PAS : ))
Information sur la source
Description
N'ayant pas eu de réponse suite à une question sur le forum sur comment lister les permissions de tous les users des dossiers partagés d'un ordi, il a bien fallu que je démerde +/- tout seul. Voici donc la solution. Vraiment pas super facile, merci Microsoft, comme d'hab : (((
Source
- #define _WIN32_WINNT 0x0500
- #include <windows.h>
- #include <stdio.h>
- #include <aclapi.h>
- #include <lmshare.h>
- #include <Lm.h>
- #include "NetEnum.h"
-
-
- /***************************************/
- /***************************************/
- /* CountNetShareEnum */
- /***************************************/
- /***************************************/
-
- DWORD CountNetShareEnum
- (
- const char* p_pcServerName,
- int* p_TotalOfShareRessource
- )
- {
- PSHARE_INFO_502 l_PShareInfo, l_BufPShareInfo;
- NET_API_STATUS l_nStatus;
- DWORD l_dwErr=0,l_dwTr=0,l_dwResume=0, i;
- LPWSTR l_pwUnicodeServerName = NULL;
- int l_iSize;
- try
- {
- // si on entre un nom de PC, on transforme le nom AINSI en UNICODE
- if (p_pcServerName != NULL)
- {
- l_iSize = strlen (p_pcServerName) + 1;
- l_pwUnicodeServerName = new WORD [l_iSize];
- l_pwUnicodeServerName[0] = 0;
- MultiByteToWideChar (CP_ACP, 0, p_pcServerName, -1, l_pwUnicodeServerName, l_iSize);
- }
-
- do // begin do
- {
- // on liste tout ou partie des dossiers partagés de p_pcServerName
- l_nStatus = NetShareEnum (l_pwUnicodeServerName, 502, (LPBYTE *) &l_BufPShareInfo, -1, &l_dwErr, &l_dwTr, &l_dwResume);
-
- if(l_nStatus != ERROR_SUCCESS && l_nStatus != ERROR_MORE_DATA)
- throw l_nStatus;
-
- // on fait pointer l_PShareInfo sur les données trouvées
- l_PShareInfo=l_BufPShareInfo;
-
- // pour chaque entrée trouvée (jusqu'à dwErr) on incrémente
- for(i=1;i<=l_dwErr;i++)
- {
- l_PShareInfo++;
- (*p_TotalOfShareRessource) ++;
- }
-
- // on libère le buffer
- NetApiBufferFree(l_BufPShareInfo);
- }
- while (l_nStatus==ERROR_MORE_DATA);
- }
- catch (DWORD)
- {
- }
- return l_nStatus;
- }
-
-
-
- /***************************************/
- /***************************************/
- /* CountNetShareEnum */
- /***************************************/
- /***************************************/
-
- DWORD RetrieveNetShareEnum
- (
- const char* p_pcServerName,
- const int p_TotalOfShareRessource,
- int* p_piCurrentIndex,
- STL_SHARE_INFO* p_ShareInfoArray
- )
- {
- PSHARE_INFO_502 l_PShareInfo, l_BufPShareInfo;
- NET_API_STATUS l_nStatus;
- DWORD l_dwCount=0,l_dwTr=0,l_dwResume=0, i;
- DWORD l_dwRetVal;
- LPWSTR l_pwUnicodeServerName = NULL;
- LPWSTR l_pwUnicodeRemark = NULL;
- LPWSTR l_pwUnicodePath = NULL;
- LPWSTR l_pwUnicodePassword = NULL;
- BOOL l_bRetVal;
- PACL l_Dacl;
- int l_iSize, l_iTotalEntriesIndex;
- unsigned long l_ulNbOfEntries = 0;
- PEXPLICIT_ACCESS l_oAccessArray = NULL;
-
- try
- {
- // si on entre un nom de PC, on transforme le nom AINSI en UNICODE
- if (p_pcServerName != NULL)
- {
- l_iSize = strlen (p_pcServerName) + 1;
- l_pwUnicodeServerName = new WORD [l_iSize];
- l_pwUnicodeServerName[0] = 0;
- MultiByteToWideChar (CP_ACP, 0, p_pcServerName, -1, l_pwUnicodeServerName, l_iSize);
- }
-
- // on mets le compteur à 0
- *p_piCurrentIndex = 0;
-
- do // begin do
- {
- // on récupère une partie des dossiers réseaux
- l_nStatus = NetShareEnum (l_pwUnicodeServerName, 502, (LPBYTE *) &l_BufPShareInfo, -1, &l_dwCount, &l_dwTr, &l_dwResume);
-
- if(l_nStatus != ERROR_SUCCESS && l_nStatus != ERROR_MORE_DATA)
- throw l_nStatus;
-
- l_PShareInfo=l_BufPShareInfo;
-
- // pour tous les dossiers trouvés, on va recopier les infos pertinentes dans notre structure STL_SHARE_INFO
- for(i=1;i<=l_dwCount;i++)
- {
- // on convertit du unicode en char pour récupérer le netname
- l_dwRetVal = WideCharToMultiByte ( CP_ACP,
- WC_NO_BEST_FIT_CHARS,
- l_PShareInfo->shi502_netname,
- -1,
- p_ShareInfoArray[*p_piCurrentIndex].cNetname,
- _MAX_PATH,
- NULL,
- NULL);
-
- if (l_dwRetVal == 0)
- throw (DWORD) "STL_UNICODE_TO_AINSI_ERROR";
-
- // on teste la validité du SID afin de ne pas lister des infos inexistantes (et faire tout exploser)
- // si le SID est invalide (NULL notamment)
- l_bRetVal = IsValidSecurityDescriptor(l_PShareInfo->shi502_security_descriptor);
-
- // si le SID est valide, on liste les infos
- if (l_bRetVal != 0)
- {
- int size = strlen (p_ShareInfoArray[*p_piCurrentIndex].cNetname) - 1;
-
- if (p_ShareInfoArray[*p_piCurrentIndex].cNetname[size] != '$')
- {
- // comme ce sont les values DWORD, on fait une copie brute de fonte
- p_ShareInfoArray[*p_piCurrentIndex].dwType = l_PShareInfo->shi502_type;
- p_ShareInfoArray[*p_piCurrentIndex].dwPermissions = l_PShareInfo->shi502_permissions;
- p_ShareInfoArray[*p_piCurrentIndex].dwMax_uses = l_PShareInfo->shi502_max_uses;
- p_ShareInfoArray[*p_piCurrentIndex].dwCurrent_uses = l_PShareInfo->shi502_current_uses;
- p_ShareInfoArray[*p_piCurrentIndex].dwReserved = l_PShareInfo->shi502_reserved;
-
- // pour les vlaues en unicode, on fait la transformation en AINSI
- l_dwRetVal = WideCharToMultiByte ( CP_ACP,
- WC_NO_BEST_FIT_CHARS,
- l_PShareInfo->shi502_remark,
- -1,
- p_ShareInfoArray[*p_piCurrentIndex].cRemark,
- _MAX_PATH,
- NULL,
- NULL);
- if (l_dwRetVal == 0)
- throw (DWORD) "STL_UNICODE_TO_AINSI_ERROR";
-
- l_dwRetVal = WideCharToMultiByte ( CP_ACP,
- WC_NO_BEST_FIT_CHARS,
- l_PShareInfo->shi502_path,
- -1,
- p_ShareInfoArray[*p_piCurrentIndex].cPath,
- _MAX_PATH,
- NULL,
- NULL);
- if (l_dwRetVal == 0)
- throw (DWORD) "STL_UNICODE_TO_AINSI_ERROR";
-
- BOOL l_bDaclPresent, l_bDaclDefault;
- /******************************************************************************************/
- /* A cet endroit, si le l_PShareInfo->shi502_security_descriptor est NULL (ou le */
- /* l_PShareInfo->shi502_reserved est = 0 (ils semblent marcher ensemble...) cela crash le */
- /* le systeme completement. Ceci peut être bypassé en délétant le rep à pb et en le */
- /* recréant... Bizarre, vous avez dit bizarre :D:D:D */
- /******************************************************************************************/
-
- // on récupère le Dacl lié au SID? C'est dans ce Dacl que l'on va trouver les infos de partage et de persmissions....
- l_bRetVal = GetSecurityDescriptorDacl(l_PShareInfo->shi502_security_descriptor, &l_bDaclPresent, &l_Dacl, &l_bDaclDefault);
-
- if (l_bRetVal == 0)
- throw (DWORD) "STL_DACL_ERROR";
-
- // on liste de façon explicite les permissions et users. La fonction renvoie un tableau de ExplicitEntries
- l_dwRetVal = GetExplicitEntriesFromAcl ( l_Dacl,
- &l_ulNbOfEntries,
- &l_oAccessArray);
-
- if (l_dwRetVal != 0)
- throw l_dwRetVal;
-
- // pour chaque entrée dans le tableau de EXPLICIT_ACCESS, on regarde si le trustee est identifié par un username, et si oui, on récupère le username et les droits d'accès
- for (l_iTotalEntriesIndex = 0; l_iTotalEntriesIndex < (int) l_ulNbOfEntries; l_iTotalEntriesIndex ++)
- {
- // on copie le
- p_ShareInfoArray[*p_piCurrentIndex].aEnumUserRights[l_iTotalEntriesIndex].AccessRights = l_oAccessArray[l_iTotalEntriesIndex].grfAccessPermissions;
-
- if (l_oAccessArray[l_iTotalEntriesIndex].Trustee.TrusteeForm == TRUSTEE_IS_NAME)
- {
- // on copie les droits (sous forme de MASK DWORD)
- strcpy(p_ShareInfoArray[*p_piCurrentIndex].aEnumUserRights[l_iTotalEntriesIndex].cUserName, l_oAccessArray[l_iTotalEntriesIndex].Trustee.ptstrName);
- }
- else
- {
- char l_cDomainName[_MAX_FNAME];
- unsigned long l_ulDomSize = _MAX_FNAME;
- unsigned long l_ulBufSize = _MAX_FNAME;
- SID_NAME_USE l_oSIDNameUse;
- DWORD l_dwErr;
-
- // pour chaque entrée du tableau, on va récupérer le Nom du user depuis le SID associé
- l_bRetVal = LookupAccountSid ( p_pcServerName,
- l_oAccessArray[l_iTotalEntriesIndex].Trustee.ptstrName,
- p_ShareInfoArray[*p_piCurrentIndex].aEnumUserRights[l_iTotalEntriesIndex].cUserName,
- &l_ulBufSize,
- l_cDomainName,
- &l_ulBufSize,
- &l_oSIDNameUse);
- if (l_bRetVal == 0)
- {
- l_dwErr = GetLastError();
- throw l_dwErr;
- }
-
- switch (l_oSIDNameUse)
- {
- case SidTypeUser :
- p_ShareInfoArray[*p_piCurrentIndex].l_oAccountType = STL_SidTypeUser;
- break;
- case SidTypeGroup :
- p_ShareInfoArray[*p_piCurrentIndex].l_oAccountType = STL_SidTypeGroup;
- break;
- case SidTypeDomain :
- p_ShareInfoArray[*p_piCurrentIndex].l_oAccountType = STL_SidTypeDomain;
- break;
- case SidTypeAlias :
- p_ShareInfoArray[*p_piCurrentIndex].l_oAccountType = STL_SidTypeAlias;
- break;
- case SidTypeWellKnownGroup :
- p_ShareInfoArray[*p_piCurrentIndex].l_oAccountType = STL_SidTypeWellKnownGroup;
- break;
- case SidTypeDeletedAccount :
- p_ShareInfoArray[*p_piCurrentIndex].l_oAccountType = STL_SidTypeDeletedAccount;
- break;
- case SidTypeInvalid :
- p_ShareInfoArray[*p_piCurrentIndex].l_oAccountType = STL_SidTypeInvalid;
- break;
- default :
- p_ShareInfoArray[*p_piCurrentIndex].l_oAccountType = STL_SidTypeUnknown;
- break;
- }//end switch
- }
-
- }// end for
- p_ShareInfoArray[*p_piCurrentIndex].iTotalUserRights = l_iTotalEntriesIndex;
- LocalFree (l_oAccessArray);
- (*p_piCurrentIndex) ++;
- }
- }
- else // si pb avec le SID
- {
- sprintf(p_ShareInfoArray[(*p_piCurrentIndex)++].cRemark, "ERREUR AVEC LE SID DE CE DOSSIER");
- }
-
- l_PShareInfo++;
- } // end for
-
- NetApiBufferFree(l_BufPShareInfo);
- l_BufPShareInfo = NULL;
- }
- while (l_nStatus==ERROR_MORE_DATA);
- }
- catch (DWORD dwErr)
- {
- l_nStatus = dwErr;
- }
- // on delete les pointeurs si OK
- if (l_BufPShareInfo != NULL)
- NetApiBufferFree(l_BufPShareInfo);
-
- return l_nStatus;
- }
#define _WIN32_WINNT 0x0500
#include <windows.h>
#include <stdio.h>
#include <aclapi.h>
#include <lmshare.h>
#include <Lm.h>
#include "NetEnum.h"
/***************************************/
/***************************************/
/* CountNetShareEnum */
/***************************************/
/***************************************/
DWORD CountNetShareEnum
(
const char* p_pcServerName,
int* p_TotalOfShareRessource
)
{
PSHARE_INFO_502 l_PShareInfo, l_BufPShareInfo;
NET_API_STATUS l_nStatus;
DWORD l_dwErr=0,l_dwTr=0,l_dwResume=0, i;
LPWSTR l_pwUnicodeServerName = NULL;
int l_iSize;
try
{
// si on entre un nom de PC, on transforme le nom AINSI en UNICODE
if (p_pcServerName != NULL)
{
l_iSize = strlen (p_pcServerName) + 1;
l_pwUnicodeServerName = new WORD [l_iSize];
l_pwUnicodeServerName[0] = 0;
MultiByteToWideChar (CP_ACP, 0, p_pcServerName, -1, l_pwUnicodeServerName, l_iSize);
}
do // begin do
{
// on liste tout ou partie des dossiers partagés de p_pcServerName
l_nStatus = NetShareEnum (l_pwUnicodeServerName, 502, (LPBYTE *) &l_BufPShareInfo, -1, &l_dwErr, &l_dwTr, &l_dwResume);
if(l_nStatus != ERROR_SUCCESS && l_nStatus != ERROR_MORE_DATA)
throw l_nStatus;
// on fait pointer l_PShareInfo sur les données trouvées
l_PShareInfo=l_BufPShareInfo;
// pour chaque entrée trouvée (jusqu'à dwErr) on incrémente
for(i=1;i<=l_dwErr;i++)
{
l_PShareInfo++;
(*p_TotalOfShareRessource) ++;
}
// on libère le buffer
NetApiBufferFree(l_BufPShareInfo);
}
while (l_nStatus==ERROR_MORE_DATA);
}
catch (DWORD)
{
}
return l_nStatus;
}
/***************************************/
/***************************************/
/* CountNetShareEnum */
/***************************************/
/***************************************/
DWORD RetrieveNetShareEnum
(
const char* p_pcServerName,
const int p_TotalOfShareRessource,
int* p_piCurrentIndex,
STL_SHARE_INFO* p_ShareInfoArray
)
{
PSHARE_INFO_502 l_PShareInfo, l_BufPShareInfo;
NET_API_STATUS l_nStatus;
DWORD l_dwCount=0,l_dwTr=0,l_dwResume=0, i;
DWORD l_dwRetVal;
LPWSTR l_pwUnicodeServerName = NULL;
LPWSTR l_pwUnicodeRemark = NULL;
LPWSTR l_pwUnicodePath = NULL;
LPWSTR l_pwUnicodePassword = NULL;
BOOL l_bRetVal;
PACL l_Dacl;
int l_iSize, l_iTotalEntriesIndex;
unsigned long l_ulNbOfEntries = 0;
PEXPLICIT_ACCESS l_oAccessArray = NULL;
try
{
// si on entre un nom de PC, on transforme le nom AINSI en UNICODE
if (p_pcServerName != NULL)
{
l_iSize = strlen (p_pcServerName) + 1;
l_pwUnicodeServerName = new WORD [l_iSize];
l_pwUnicodeServerName[0] = 0;
MultiByteToWideChar (CP_ACP, 0, p_pcServerName, -1, l_pwUnicodeServerName, l_iSize);
}
// on mets le compteur à 0
*p_piCurrentIndex = 0;
do // begin do
{
// on récupère une partie des dossiers réseaux
l_nStatus = NetShareEnum (l_pwUnicodeServerName, 502, (LPBYTE *) &l_BufPShareInfo, -1, &l_dwCount, &l_dwTr, &l_dwResume);
if(l_nStatus != ERROR_SUCCESS && l_nStatus != ERROR_MORE_DATA)
throw l_nStatus;
l_PShareInfo=l_BufPShareInfo;
// pour tous les dossiers trouvés, on va recopier les infos pertinentes dans notre structure STL_SHARE_INFO
for(i=1;i<=l_dwCount;i++)
{
// on convertit du unicode en char pour récupérer le netname
l_dwRetVal = WideCharToMultiByte ( CP_ACP,
WC_NO_BEST_FIT_CHARS,
l_PShareInfo->shi502_netname,
-1,
p_ShareInfoArray[*p_piCurrentIndex].cNetname,
_MAX_PATH,
NULL,
NULL);
if (l_dwRetVal == 0)
throw (DWORD) "STL_UNICODE_TO_AINSI_ERROR";
// on teste la validité du SID afin de ne pas lister des infos inexistantes (et faire tout exploser)
// si le SID est invalide (NULL notamment)
l_bRetVal = IsValidSecurityDescriptor(l_PShareInfo->shi502_security_descriptor);
// si le SID est valide, on liste les infos
if (l_bRetVal != 0)
{
int size = strlen (p_ShareInfoArray[*p_piCurrentIndex].cNetname) - 1;
if (p_ShareInfoArray[*p_piCurrentIndex].cNetname[size] != '$')
{
// comme ce sont les values DWORD, on fait une copie brute de fonte
p_ShareInfoArray[*p_piCurrentIndex].dwType = l_PShareInfo->shi502_type;
p_ShareInfoArray[*p_piCurrentIndex].dwPermissions = l_PShareInfo->shi502_permissions;
p_ShareInfoArray[*p_piCurrentIndex].dwMax_uses = l_PShareInfo->shi502_max_uses;
p_ShareInfoArray[*p_piCurrentIndex].dwCurrent_uses = l_PShareInfo->shi502_current_uses;
p_ShareInfoArray[*p_piCurrentIndex].dwReserved = l_PShareInfo->shi502_reserved;
// pour les vlaues en unicode, on fait la transformation en AINSI
l_dwRetVal = WideCharToMultiByte ( CP_ACP,
WC_NO_BEST_FIT_CHARS,
l_PShareInfo->shi502_remark,
-1,
p_ShareInfoArray[*p_piCurrentIndex].cRemark,
_MAX_PATH,
NULL,
NULL);
if (l_dwRetVal == 0)
throw (DWORD) "STL_UNICODE_TO_AINSI_ERROR";
l_dwRetVal = WideCharToMultiByte ( CP_ACP,
WC_NO_BEST_FIT_CHARS,
l_PShareInfo->shi502_path,
-1,
p_ShareInfoArray[*p_piCurrentIndex].cPath,
_MAX_PATH,
NULL,
NULL);
if (l_dwRetVal == 0)
throw (DWORD) "STL_UNICODE_TO_AINSI_ERROR";
BOOL l_bDaclPresent, l_bDaclDefault;
/******************************************************************************************/
/* A cet endroit, si le l_PShareInfo->shi502_security_descriptor est NULL (ou le */
/* l_PShareInfo->shi502_reserved est = 0 (ils semblent marcher ensemble...) cela crash le */
/* le systeme completement. Ceci peut être bypassé en délétant le rep à pb et en le */
/* recréant... Bizarre, vous avez dit bizarre :D:D:D */
/******************************************************************************************/
// on récupère le Dacl lié au SID? C'est dans ce Dacl que l'on va trouver les infos de partage et de persmissions....
l_bRetVal = GetSecurityDescriptorDacl(l_PShareInfo->shi502_security_descriptor, &l_bDaclPresent, &l_Dacl, &l_bDaclDefault);
if (l_bRetVal == 0)
throw (DWORD) "STL_DACL_ERROR";
// on liste de façon explicite les permissions et users. La fonction renvoie un tableau de ExplicitEntries
l_dwRetVal = GetExplicitEntriesFromAcl ( l_Dacl,
&l_ulNbOfEntries,
&l_oAccessArray);
if (l_dwRetVal != 0)
throw l_dwRetVal;
// pour chaque entrée dans le tableau de EXPLICIT_ACCESS, on regarde si le trustee est identifié par un username, et si oui, on récupère le username et les droits d'accès
for (l_iTotalEntriesIndex = 0; l_iTotalEntriesIndex < (int) l_ulNbOfEntries; l_iTotalEntriesIndex ++)
{
// on copie le
p_ShareInfoArray[*p_piCurrentIndex].aEnumUserRights[l_iTotalEntriesIndex].AccessRights = l_oAccessArray[l_iTotalEntriesIndex].grfAccessPermissions;
if (l_oAccessArray[l_iTotalEntriesIndex].Trustee.TrusteeForm == TRUSTEE_IS_NAME)
{
// on copie les droits (sous forme de MASK DWORD)
strcpy(p_ShareInfoArray[*p_piCurrentIndex].aEnumUserRights[l_iTotalEntriesIndex].cUserName, l_oAccessArray[l_iTotalEntriesIndex].Trustee.ptstrName);
}
else
{
char l_cDomainName[_MAX_FNAME];
unsigned long l_ulDomSize = _MAX_FNAME;
unsigned long l_ulBufSize = _MAX_FNAME;
SID_NAME_USE l_oSIDNameUse;
DWORD l_dwErr;
// pour chaque entrée du tableau, on va récupérer le Nom du user depuis le SID associé
l_bRetVal = LookupAccountSid ( p_pcServerName,
l_oAccessArray[l_iTotalEntriesIndex].Trustee.ptstrName,
p_ShareInfoArray[*p_piCurrentIndex].aEnumUserRights[l_iTotalEntriesIndex].cUserName,
&l_ulBufSize,
l_cDomainName,
&l_ulBufSize,
&l_oSIDNameUse);
if (l_bRetVal == 0)
{
l_dwErr = GetLastError();
throw l_dwErr;
}
switch (l_oSIDNameUse)
{
case SidTypeUser :
p_ShareInfoArray[*p_piCurrentIndex].l_oAccountType = STL_SidTypeUser;
break;
case SidTypeGroup :
p_ShareInfoArray[*p_piCurrentIndex].l_oAccountType = STL_SidTypeGroup;
break;
case SidTypeDomain :
p_ShareInfoArray[*p_piCurrentIndex].l_oAccountType = STL_SidTypeDomain;
break;
case SidTypeAlias :
p_ShareInfoArray[*p_piCurrentIndex].l_oAccountType = STL_SidTypeAlias;
break;
case SidTypeWellKnownGroup :
p_ShareInfoArray[*p_piCurrentIndex].l_oAccountType = STL_SidTypeWellKnownGroup;
break;
case SidTypeDeletedAccount :
p_ShareInfoArray[*p_piCurrentIndex].l_oAccountType = STL_SidTypeDeletedAccount;
break;
case SidTypeInvalid :
p_ShareInfoArray[*p_piCurrentIndex].l_oAccountType = STL_SidTypeInvalid;
break;
default :
p_ShareInfoArray[*p_piCurrentIndex].l_oAccountType = STL_SidTypeUnknown;
break;
}//end switch
}
}// end for
p_ShareInfoArray[*p_piCurrentIndex].iTotalUserRights = l_iTotalEntriesIndex;
LocalFree (l_oAccessArray);
(*p_piCurrentIndex) ++;
}
}
else // si pb avec le SID
{
sprintf(p_ShareInfoArray[(*p_piCurrentIndex)++].cRemark, "ERREUR AVEC LE SID DE CE DOSSIER");
}
l_PShareInfo++;
} // end for
NetApiBufferFree(l_BufPShareInfo);
l_BufPShareInfo = NULL;
}
while (l_nStatus==ERROR_MORE_DATA);
}
catch (DWORD dwErr)
{
l_nStatus = dwErr;
}
// on delete les pointeurs si OK
if (l_BufPShareInfo != NULL)
NetApiBufferFree(l_BufPShareInfo);
return l_nStatus;
}
Conclusion
Ne pas oublier de linker les lib advapi32.lib, mpr.lib et netapi32.lib. Voila, cela peut peut être servir....
Sources du même auteur
Sources de la même categorie
Commentaires et avis
|
Derniers Blogs
ARTICLE DANS PROGRAMMEZ SUR LES PRINCIPES SOLIDARTICLE DANS PROGRAMMEZ SUR LES PRINCIPES SOLID par fathi
Hello tout le monde! J'ai pas pu blogger ces derniers temps car j'ai eu un (heureux) petit chamboulement dans ma vie perso (un "bug" de 3.8 kg et de 52 cm) J'en profite juste pour vous annoncer la parution d'un article sur les principes SOLID ...
Cliquez pour lire la suite de l'article par fathi PARUTION DE MON LIVRE SUR WPF 4PARUTION DE MON LIVRE SUR WPF 4 par odewit
La 2e édition de mon livre sur WPF sort aujourd'hui en version numérique et lundi en version papier :-)
L'ouvrage présente de façon approfondie les fonctionnalités de WPF 4 : graphisme 2D et 3D, animation, multimédia, interfaces utilisateur, databind...
Cliquez pour lire la suite de l'article par odewit EDM : COMMENT UTILISER L'HORIZONTAL ENTITY SPLITTINGEDM : COMMENT UTILISER L'HORIZONTAL ENTITY SPLITTING par Matthieu MEZIL
Une des raisons pour lesquelles j'adore l'Entity Framework est la puissance de son mapping. Beaucoup de développeurs pour ne pas dire la plus part n'en n'ont pas conscience. Pour rappel, j'ai réalisé des videos (en anglais) sur le mapping . Certains scena...
Cliquez pour lire la suite de l'article par Matthieu MEZIL [WP7DEV][REACTIVE] RENDRE LES REACTIVE EXTENSIONS PLUS STABLES[WP7DEV][REACTIVE] RENDRE LES REACTIVE EXTENSIONS PLUS STABLES par jay
Lorsque l'on développe des applications .NET, les exceptions non gérées dans des threads ont le désagréable effet de terminer le processus courant.
Dans l'exemple suivant.......(read more) ...
Cliquez pour lire la suite de l'article par jay
Forum
DE L'AIIIDE!!DE L'AIIIDE!! par eliramomo
Cliquez pour lire la suite par eliramomo
Logiciels
Microsoft Office (2010)MICROSOFT OFFICE (2010)Microsoft Office 2010 offre de nouveaux moyens flexibles et puissants pour optimiser votre travai... Cliquez pour télécharger Microsoft Office SeaMonkey (2.0.7)SEAMONKEY (2.0.7)Le projet SeaMonkey est issu d'un effort communautaire pour developper une application tout en un... Cliquez pour télécharger SeaMonkey Safari (5.0.2)SAFARI (5.0.2)Le navigateur d'Apple a lui aussi été mis à jour, aussi bien dans sa mouture Windows que celle po... Cliquez pour télécharger Safari Mozilla FireFox (4.0 béta 5)MOZILLA FIREFOX (4.0 BéTA 5)Firefox 4.0 béta 5
L'une des nouveautés visibles les plus attendues réside sans doute dans l'a... Cliquez pour télécharger Mozilla FireFox Mozilla Firefox (3.6.9)MOZILLA FIREFOX (3.6.9)Firefox 3.6.9 corrige les problèmes suivants :
* Introduced support for the X-FRAME-OPTION... Cliquez pour télécharger Mozilla Firefox
|