Changeset 361

Show
Ignore:
Timestamp:
08/01/08 12:19:46 (9 years ago)
Author:
rsteenson
Message:

Finally connects to server, visits urls and cleans your room

  • Rewrote file monitor kernel driver. Partially finished
  • Started refactoring EventManager? so that other handlers can be used
  • Elements are now the comms events, these are XML type objects.
  • Event is now the super fast internal event that is used in the monitors, not yet finished though
Location:
capture-hpc/branches/dev/capture-client
Files:
4 added
30 modified

Legend:

Unmodified
Added
Removed
  • capture-hpc/branches/dev/capture-client/CaptureClient.cpp

    r360 r361  
    232232// server id and virtual machine id this client is hosted on back to the server 
    233233void 
    234 CaptureClient::onServerConnectEvent(const std::wstring& event_type, const Event& event) 
     234CaptureClient::onServerConnectEvent(const std::wstring& event_type, const Element& e) 
    235235{ 
    236236        LOG(INFO, "CaptureClient: Received connect event"); 
     
    247247// Sends a pong message back to the server when a ping is received 
    248248void 
    249 CaptureClient::onServerPingEvent(const std::wstring& event_type, const Event& event) 
     249CaptureClient::onServerPingEvent(const std::wstring& event_type, const Element& e) 
    250250{ 
    251251        LOG(INFO, "CaptureClient: Received ping event"); 
  • capture-hpc/branches/dev/capture-client/CaptureClient.h

    r352 r361  
    3030 
    3131        void onConnectionStatusChanged(bool connectionStatus); 
    32         void onServerConnectEvent(const std::wstring& event_type, const Event& element); 
    33         void onServerPingEvent(const std::wstring& event_type, const Event& element); 
     32        void onServerConnectEvent(const std::wstring& event_type, const Element& e); 
     33        void onServerPingEvent(const std::wstring& event_type, const Element& e); 
    3434 
    3535        Server* server; 
  • capture-hpc/branches/dev/capture-client/CaptureClient.vcproj

    r360 r361  
    127127                                AdditionalIncludeDirectories="Libraries\ZipArchive;Libraries\wpcap\Include;Libraries\expat\lib" 
    128128                                PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;WARN;CAPTURE_DEBUG" 
    129                                 RuntimeLibrary="3" 
     129                                StringPooling="true" 
     130                                RuntimeLibrary="2" 
     131                                BufferSecurityCheck="false" 
    130132                                UsePrecompiledHeader="0" 
    131133                                WarningLevel="3" 
     
    152154                                OptimizeReferences="2" 
    153155                                EnableCOMDATFolding="2" 
    154                                 OptimizeForWindows98="1" 
     156                                OptimizeForWindows98="0" 
    155157                                RandomizedBaseAddress="1" 
    156158                                DataExecutionPrevention="0" 
     
    381383                        > 
    382384                        <File 
     385                                RelativePath=".\Element.cpp" 
     386                                > 
     387                        </File> 
     388                        <File 
    383389                                RelativePath=".\Element.h" 
    384390                                > 
     
    442448                        <File 
    443449                                RelativePath=".\EventRouter.h" 
     450                                > 
     451                        </File> 
     452                        <File 
     453                                RelativePath=".\FastDelegate.h" 
    444454                                > 
    445455                        </File> 
     
    699709                <File 
    700710                        RelativePath=".\Analyzer.h" 
     711                        > 
     712                </File> 
     713                <File 
     714                        RelativePath=".\BlockingQueue.h" 
    701715                        > 
    702716                </File> 
  • capture-hpc/branches/dev/capture-client/Element.h

    r351 r361  
    33#include <string> 
    44 
    5 class Attribute 
     5//class Attribute 
     6//{ 
     7//public: 
     8//      Attribute(const std::wstring& n, const std::wstring& v) { name = n; value = v; } 
     9//      virtual ~Attribute() {} 
     10//       
     11//      inline const std::wstring& getName() const { return name; } 
     12//      inline const std::wstring& getValue() const { return value; } 
     13// 
     14//private: 
     15//      std::wstring name; 
     16//      std::wstring value; 
     17//}; 
     18// 
     19//class Element 
     20//{ 
     21//public: 
     22//      Element() 
     23//      { 
     24//              parent = NULL; 
     25//              data = NULL; 
     26//              dataSize = 0; 
     27//              _hasParent = false; 
     28//      } 
     29// 
     30//      virtual ~Element() 
     31//      { 
     32//              attributes.clear(); 
     33//              for each(Element* child in childElements) 
     34//              { 
     35//                      //delete child; 
     36//              } 
     37//              free(data); 
     38//              dataSize = 0; 
     39//      } 
     40// 
     41//      void addAttribute(const std::wstring& name, const std::wstring& value) 
     42//      { 
     43//              attributes.push_back(Attribute(name, value)); 
     44//      } 
     45// 
     46//      const std::wstring getAttributeValue(const std::wstring& name) const 
     47//      { 
     48//              for each(Attribute a in attributes) 
     49//              { 
     50//                      if(a.getName() == name) 
     51//                      { 
     52//                              return a.getValue(); 
     53//                      } 
     54//              } 
     55//              return std::wstring(); 
     56//      } 
     57// 
     58//      void addChildElement(Element* childElement) 
     59//      { 
     60//              childElement->setParent(this); 
     61//              childElements.push_back(childElement); 
     62//      } 
     63// 
     64//      void setData(const char* data, size_t dataSize) 
     65//      { 
     66//              this->data = (char*)malloc(dataSize); 
     67//              memcpy(this->data, data, dataSize); 
     68//              this->dataSize = dataSize; 
     69//      } 
     70// 
     71//      void setName(const std::wstring& elementName) 
     72//      { 
     73//              name = elementName; 
     74//      } 
     75// 
     76//      void setParent(Element* element) 
     77//      { 
     78//              parent = element; 
     79//              _hasParent = true; 
     80//      } 
     81// 
     82//      std::wstring toString() const 
     83//      { 
     84//              std::wstring document = toStringWithoutNewLine(); 
     85//              document += L"\r\n"; 
     86//              return document; 
     87//      } 
     88//       
     89//      std::wstring toStringWithoutNewLine() const 
     90//      { 
     91//              std::wstring document = L"<"; 
     92//              document += name; 
     93//              for each(Attribute attribute in attributes) 
     94//              { 
     95//                      document += L" "; 
     96//                      document += attribute.getName(); 
     97//                      document += L"=\""; 
     98//                      document += attribute.getValue(); 
     99//                      document += L"\""; 
     100//              } 
     101// 
     102//              document += L">"; 
     103// 
     104//              if(childElements.size() > 0) 
     105//              { 
     106//                      _ASSERT(dataSize == 0); 
     107// 
     108//                      for each(Element* childElement in childElements) 
     109//                      { 
     110//                              document += childElement->toStringWithoutNewLine(); 
     111//                      } 
     112//              } 
     113// 
     114//              if(dataSize > 0) 
     115//              { 
     116//                      _ASSERT(childElements.size() == 0); 
     117//                      // TODO fix this ugly hack, data uses up twice the amount of space it should 
     118//                      wchar_t* tempData = (wchar_t*)malloc((dataSize+1)*sizeof(wchar_t)); 
     119//                      for(unsigned int i = 0; i < dataSize; i++) 
     120//                      { 
     121//                              // We get away with this cast for now as the data is base64 encoded 
     122//                              // so will always be an ASCII char and map correctly to a unicode wchar 
     123//                              tempData[i] = (wchar_t)data[i]; 
     124//                      } 
     125//                      tempData[dataSize] = '\0'; 
     126//                      document += tempData; 
     127//                      free(tempData); 
     128//              } 
     129// 
     130//              document += L"</"; 
     131//              document += name; 
     132//              document += L">"; 
     133// 
     134//              return document; 
     135//      } 
     136// 
     137//      inline const std::wstring& getName() const { return name; } 
     138//      inline const std::vector<Attribute>& getAttributes() const { return attributes; } 
     139//      inline Element* getParent() { return parent; } 
     140//      inline const char* getData() const { return data; } 
     141//      inline const std::vector<Element*>& getChildElements() const { return childElements; } 
     142//      inline const size_t getDataSize() const { return dataSize; } 
     143//      inline bool hasParent() { return _hasParent; } 
     144// 
     145//private: 
     146//      bool _hasParent; 
     147//      std::wstring name; 
     148//      std::vector<Attribute> attributes; 
     149//      char * data; 
     150//      size_t dataSize; 
     151//      std::vector<Element*> childElements; 
     152//      Element* parent; 
     153//}; 
     154 
     155#include <hash_map> 
     156#include <vector> 
     157 
     158class Data 
    6159{ 
    7160public: 
    8         Attribute(const std::wstring& n, const std::wstring& v) { name = n; value = v; } 
    9         virtual ~Attribute() {} 
    10          
    11         inline const std::wstring& getName() const { return name; } 
    12         inline const std::wstring& getValue() const { return value; } 
     161        Data() : m_Data(NULL), m_Size(0) 
     162        { 
     163        } 
     164 
     165        Data(unsigned char* data, unsigned int size) 
     166                : m_Data(NULL), m_Size(0) 
     167        { 
     168                m_Data = (unsigned char*)malloc(size + sizeof(wchar_t)); 
     169                if(m_Data) 
     170                { 
     171                        memcpy(m_Data, data, size); 
     172                        m_Data[size] = '\0'; 
     173                        m_Size = size; 
     174                } 
     175        } 
     176        ~Data() 
     177        { 
     178                if(m_Data) 
     179                { 
     180                        free(m_Data); 
     181                } 
     182        } 
     183 
     184        void ToString(std::wstring& data) 
     185        { 
     186                wchar_t c[2]; 
     187                c[1] = '\0'; 
     188 
     189                for(unsigned int i = 0; i < m_Size; ++i) 
     190                { 
     191                        c[0] = (wchar_t)m_Data[i]; 
     192                        data.append(c); 
     193                } 
     194        } 
     195 
     196        bool IsEmpty()  { return (m_Data == NULL); } 
    13197 
    14198private: 
    15         std::wstring name; 
    16         std::wstring value; 
     199        unsigned char*  m_Data; 
     200        unsigned int    m_Size; 
    17201}; 
     202 
     203class Element; 
     204 
     205typedef std::vector<Element*>                                                   ChildElementList; 
     206typedef stdext::hash_map<std::wstring, std::wstring>    AttributeMap; 
     207typedef AttributeMap::iterator                                                  AttributeIterator; 
    18208 
    19209class Element 
    20210{ 
     211         
     212        typedef std::vector<Element*>::iterator                                 ChildrenIterator; 
     213         
    21214public: 
    22         Element() 
    23         { 
    24                 parent = NULL; 
    25                 data = NULL; 
    26                 dataSize = 0; 
    27                 _hasParent = false; 
    28         } 
    29  
    30         virtual ~Element() 
    31         { 
    32                 attributes.clear(); 
    33                 for each(Element* child in childElements) 
    34                 { 
    35                         //delete child; 
    36                 } 
    37                 free(data); 
    38                 dataSize = 0; 
    39         } 
    40  
    41         void addAttribute(const std::wstring& name, const std::wstring& value) 
    42         { 
    43                 attributes.push_back(Attribute(name, value)); 
    44         } 
    45  
    46         const std::wstring getAttributeValue(const std::wstring& name) const 
    47         { 
    48                 for each(Attribute a in attributes) 
    49                 { 
    50                         if(a.getName() == name) 
    51                         { 
    52                                 return a.getValue(); 
    53                         } 
    54                 } 
    55                 return std::wstring(); 
    56         } 
    57  
    58         void addChildElement(Element* childElement) 
    59         { 
    60                 childElement->setParent(this); 
    61                 childElements.push_back(childElement); 
    62         } 
    63  
    64         void setData(const char* data, size_t dataSize) 
    65         { 
    66                 this->data = (char*)malloc(dataSize); 
    67                 memcpy(this->data, data, dataSize); 
    68                 this->dataSize = dataSize; 
    69         } 
    70  
    71         void setName(const std::wstring& elementName) 
    72         { 
    73                 name = elementName; 
    74         } 
    75  
    76         void setParent(Element* element) 
    77         { 
    78                 parent = element; 
    79                 _hasParent = true; 
    80         } 
    81  
    82         std::wstring toString() const 
    83         { 
    84                 std::wstring document = toStringWithoutNewLine(); 
    85                 document += L"\r\n"; 
    86                 return document; 
    87         } 
    88          
    89         std::wstring toStringWithoutNewLine() const 
    90         { 
    91                 std::wstring document = L"<"; 
    92                 document += name; 
    93                 for each(Attribute attribute in attributes) 
    94                 { 
    95                         document += L" "; 
    96                         document += attribute.getName(); 
    97                         document += L"=\""; 
    98                         document += attribute.getValue(); 
    99                         document += L"\""; 
    100                 } 
    101  
    102                 document += L">"; 
    103  
    104                 if(childElements.size() > 0) 
    105                 { 
    106                         _ASSERT(dataSize == 0); 
    107  
    108                         for each(Element* childElement in childElements) 
    109                         { 
    110                                 document += childElement->toStringWithoutNewLine(); 
    111                         } 
    112                 } 
    113  
    114                 if(dataSize > 0) 
    115                 { 
    116                         _ASSERT(childElements.size() == 0); 
    117                         // TODO fix this ugly hack, data uses up twice the amount of space it should 
    118                         wchar_t* tempData = (wchar_t*)malloc((dataSize+1)*sizeof(wchar_t)); 
    119                         for(unsigned int i = 0; i < dataSize; i++) 
    120                         { 
    121                                 // We get away with this cast for now as the data is base64 encoded 
    122                                 // so will always be an ASCII char and map correctly to a unicode wchar 
    123                                 tempData[i] = (wchar_t)data[i]; 
    124                         } 
    125                         tempData[dataSize] = '\0'; 
    126                         document += tempData; 
    127                         free(tempData); 
    128                 } 
    129  
    130                 document += L"</"; 
    131                 document += name; 
    132                 document += L">"; 
    133  
    134                 return document; 
    135         } 
    136  
    137         inline const std::wstring& getName() const { return name; } 
    138         inline const std::vector<Attribute>& getAttributes() const { return attributes; } 
    139         inline Element* getParent() { return parent; } 
    140         inline const char* getData() const { return data; } 
    141         inline const std::vector<Element*>& getChildElements() const { return childElements; } 
    142         inline const size_t getDataSize() const { return dataSize; } 
    143         inline bool hasParent() { return _hasParent; } 
    144  
    145 private: 
    146         bool _hasParent; 
    147         std::wstring name; 
    148         std::vector<Attribute> attributes; 
    149         char * data; 
    150         size_t dataSize; 
    151         std::vector<Element*> childElements; 
    152         Element* parent; 
     215        Element(); 
     216        virtual ~Element(); 
     217 
     218        void ToString(std::wstring& element); 
     219         
     220        const AttributeMap&             GetAttributes()         const { return m_Attributes; } 
     221        const ChildElementList& GetChildElements()      const { return m_Children; } 
     222 
     223        void SetName(const std::wstring& name)  { m_Name = name; } 
     224        void SetAttribute(const std::wstring& attribute, const std::wstring& value); 
     225         
     226        void AddElement(Element* child) { child->SetParent(this); m_Children.push_back(child); } 
     227        void AddAttribute(const std::wstring& attribute, const std::wstring& value); 
     228         
     229        const Data&                     GetData() const { return m_Data; } 
     230        const std::wstring&     GetName() const { return m_Name; } 
     231        const std::wstring&     GetAttribute(const std::wstring& attribute) const { return m_Attributes.find(attribute)->second; } 
     232 
     233        bool HasParent()                { return (m_Parent != NULL); } 
     234        Element* GetParent()    { return m_Parent; } 
     235        void SetParent(Element* parent) { m_Parent = parent; } 
     236 
     237private:        // Disable copy and assignment 
     238        Element(const Element& e); 
     239        Element& operator=(const Element& e); 
     240 
     241protected: 
     242        Element*                                m_Parent; 
     243        std::wstring                    m_Name; 
     244        Data                                    m_Data;  
     245        AttributeMap                    m_Attributes; 
     246        ChildElementList                m_Children; 
    153247}; 
  • capture-hpc/branches/dev/capture-client/ElementHandler.h

    r352 r361  
    44{ 
    55public: 
    6         virtual void startElement(void *user_data, const char* name, const char** attributes)  = 0; 
    7         virtual void endElement(void *user_data, const char* name) = 0; 
     6        virtual void startElement(void *user_data, const wchar_t* name, const wchar_t** attributes)  = 0; 
     7        virtual void endElement(void *user_data, const wchar_t* name) = 0; 
    88        virtual void charData(void *user_data, const char* data, int length) = 0; 
    99}; 
  • capture-hpc/branches/dev/capture-client/Event.h

    r352 r361  
    11#pragma once 
     2#include "Element.h" 
    23#include "Variant.h" 
    34#include "XmlObject.h" 
     
    56#include <hash_map> 
    67#include <vector> 
    7  
    8 class Event : public XmlObject 
     8#include "SystemEvent.h" 
     9 
     10typedef unsigned long CRC; 
     11 
     12class Event 
    913{ 
     14        typedef stdext::hash_map<unsigned int, Variant*>::iterator DataIterator; 
    1015public: 
    11         Event(void) 
    12         { 
    13                 data = NULL; 
    14                 data_size = 0; 
    15                 parent_event = NULL; 
    16         } 
    17  
    18         Event(const std::wstring& name) 
    19         { 
    20                 setName(name); 
    21                 data = NULL; 
    22                 data_size = 0; 
    23                 parent_event = NULL; 
    24         } 
    25  
    26         virtual ~Event(void) 
    27         { 
    28                 if(data) 
     16        Event() : m_Parent(NULL) 
     17        { 
     18        } 
     19 
     20        virtual ~Event() 
     21        { 
     22                for(DataIterator it = m_Data.begin(); it != m_Data.end(); it++) 
    2923                { 
    30                         free(data); 
     24                        delete it->second; 
    3125                } 
    32         } 
    33  
    34         virtual bool toXmlElement(XmlElement& xml_element) 
    35         { 
    36                 _ASSERT(false); // Not implemented yet 
    37                 return false; 
    38         } 
    39  
    40         template <class T> 
    41         void addAttribute(const std::wstring& name, const T& value) 
    42         { 
    43                 Variant* var_value = new Variant(value); 
    44                 attributes.insert(std::pair<std::wstring, Variant*>(name, var_value)); 
    45         } 
    46  
    47         template <class T> 
    48         T getAttributeValue(const std::wstring& name) const 
    49         { 
    50                 stdext::hash_map<std::wstring, Variant*>::const_iterator it; 
    51                 for(it = attributes.begin(); it != attributes.end(); it++) 
     26                m_Data.clear(); 
     27        } 
     28 
     29        Event(const Event& e) 
     30        { 
     31                _ASSERT(false); // Shouldn't really be copying these about 
     32                m_Data = e.m_Data; 
     33        } 
     34 
     35        Event& operator=(const Event& e) 
     36        { 
     37                _ASSERT(false); // Shouldn't really be copying these about 
     38                if(this != &e) 
     39                        m_Data = e.m_Data; 
     40                return *this; 
     41        } 
     42 
     43        template <class T> 
     44        void SetData(CRC key, const T& value) 
     45        { 
     46                DataIterator it = m_Data.find(key); 
     47                if(it != m_Data.end()) 
    5248                { 
    53                         if(it->first == name) 
    54                         { 
    55                                 return it->second->getValue<T>(); 
    56                         } 
     49                        it->second->change(value); 
    5750                } 
    58                 return T(); 
    59         } 
    60  
    61         void setData(const char* event_data, unsigned int length) 
    62         { 
    63                 data = (char*)malloc(length); 
    64                 data_size = length; 
    65                 memcpy(data, event_data, length); 
    66         } 
    67  
    68         // For the time being just make a string instead of an actual XmlElement object 
    69         // At first there was going to be a general XmlElement object which the Event class 
    70         // used as a base however it wasn't really needed ... for the time being 
    71         std::wstring toXmlElement() 
    72         { 
    73                 std::wstring document = L"<"; 
    74                 document += type; 
    75                 _ASSERT(false); 
    76  
    77                 //stdext::hash_map<std::wstring, std::wstring>::iterator it; 
    78                 //for(it = attributes.begin(); it != attributes.end(); it++) 
    79                 //{ 
    80                 //      document += L" "; 
    81                 //      document += it->first; 
    82                 //      document += L"=\""; 
    83                 //      _ASSERT(false); 
    84                 //      //document += it->second->toString(); 
    85                 //      document += L"\""; 
    86                 //} 
    87  
    88                 //document += L">"; 
    89  
    90                 //if(child_events.size() > 0) 
    91                 //{ 
    92                 //      _ASSERT(data_size == 0); 
    93  
    94                 //      std::vector<Event*>::iterator c_it; 
    95                 //      for(c_it = child_events.begin(); c_it != child_events.end(); c_it++) 
    96                 //      { 
    97                 //              document += (*it)->toXmlElement(); 
    98                 //      } 
    99                 //} 
    100  
    101                 //if(data_size > 0) 
    102                 //{ 
    103                 //      _ASSERT(child_events.size() == 0); 
    104                 // 
    105                 //      document += data; 
    106                 //} 
    107  
    108                 //document += L"</"; 
    109                 //document += name; 
    110                 //document += L">\r\n"; 
    111  
    112                 return document; 
    113         } 
    114  
    115         void addChildEvent(Event* e) 
    116         { 
    117                 e->setParent(this); 
    118                 child_events.push_back(e); 
    119         } 
    120  
    121         void setParent(Event* parent) 
    122         { 
    123                 parent_event = parent; 
    124         } 
    125  
    126         void setName(const std::wstring& name) 
    127         { 
    128                 type = name; 
    129         } 
    130  
    131         inline bool hasParent() { return (parent_event != NULL); } 
    132         inline Event* getParent() { return parent_event; } 
    133         inline std::wstring getName() { return type; } 
    134         inline const std::vector<Event*>& getChildEvents() const { return child_events; } 
    135         inline const stdext::hash_map<std::wstring, Variant*>& getAttributes() const { return attributes; } 
     51                else 
     52                { 
     53                        Variant* v = new Variant(value); 
     54                        m_Data.insert(std::pair<unsigned int, Variant*>(key, v)); 
     55                } 
     56        } 
     57 
     58        template <class T> 
     59        void SetData(const char* key, const T& value) 
     60        { 
     61                SetData(crc32(key), value); 
     62        } 
     63 
     64        template <class T> 
     65        void AddData(CRC key, const T& value) 
     66        { 
     67                SetData(key, value); 
     68        } 
     69 
     70        template <class T> 
     71        void AddData(const std::wstring& key, const T& value) 
     72        { 
     73                SetData(crc32w(key.c_str()), value); 
     74        } 
     75 
     76        template <class T> 
     77        void AddData(const char* key, const T& value) 
     78        { 
     79                SetData(key, value); 
     80        } 
     81 
     82        //template <class T> 
     83        //T GetData(CRC key) 
     84        //{ 
     85        //      Variant* v = m_Data[key]; 
     86        //      return v->getValue<T>(); 
     87        //} 
     88 
     89        template <class T> 
     90        T GetData(const wchar_t* key) const 
     91        { 
     92                Variant* v = m_Data.find(crc32w(key))->second; 
     93                return v->getValue<T>(); 
     94                //return GetData(crc32(key), value); 
     95        } 
     96 
     97        void SetName(const std::wstring& name) { m_Name = name; } 
     98        const std::wstring& GetName() const { return m_Name; } 
     99 
     100        void AddChildEvent(Event* e) { e->SetParent(this); m_Children.push_back(e); } 
     101 
     102        const std::vector<Event*>& GetChildEvents() const { return m_Children; } 
     103 
     104        bool HasParent() { return (m_Parent != NULL); } 
     105        Event* GetParent() { return m_Parent; } 
     106        void SetParent(Event* parent) { m_Parent = parent; } 
    136107 
    137108private: 
    138         std::wstring type; 
    139         stdext::hash_map<std::wstring, Variant*> attributes; 
    140  
    141         Event* parent_event; 
    142         std::vector<Event*> child_events; 
    143          
    144         unsigned int data_size; 
    145         char* data; 
     109        std::wstring m_Name; 
     110 
     111        Event*  m_Parent; 
     112 
     113        std::vector<Event*>     m_Children; 
     114 
     115        stdext::hash_map<unsigned int, Variant*>        m_Data; 
    146116}; 
     117 
     118//class Event : public XmlObject 
     119//{ 
     120//public: 
     121//      Event(void) 
     122//      { 
     123//              data = NULL; 
     124//              data_size = 0; 
     125//              parent_event = NULL; 
     126//      } 
     127// 
     128//      Event(const std::wstring& name) 
     129//      { 
     130//              setName(name); 
     131//              data = NULL; 
     132//              data_size = 0; 
     133//              parent_event = NULL; 
     134//      } 
     135// 
     136//      virtual ~Event(void) 
     137//      { 
     138//              if(data) 
     139//              { 
     140//                      free(data); 
     141//              } 
     142//      } 
     143// 
     144//      virtual bool toXmlElement(XmlElement& xml_element) 
     145//      { 
     146//              _ASSERT(false); // Not implemented yet 
     147//              return false; 
     148//      } 
     149// 
     150//      template <class T> 
     151//      void addAttribute(const std::wstring& name, const T& value) 
     152//      { 
     153//              Variant* var_value = new Variant(value); 
     154//              attributes.insert(std::pair<std::wstring, Variant*>(name, var_value)); 
     155//      } 
     156// 
     157//      template <class T> 
     158//      T getAttributeValue(const std::wstring& name) const 
     159//      { 
     160//              stdext::hash_map<std::wstring, Variant*>::const_iterator it; 
     161//              for(it = attributes.begin(); it != attributes.end(); it++) 
     162//              { 
     163//                      if(it->first == name) 
     164//                      { 
     165//                              return it->second->getValue<T>(); 
     166//                      } 
     167//              } 
     168//              return T(); 
     169//      } 
     170// 
     171//      void setData(const char* event_data, unsigned int length) 
     172//      { 
     173//              data = (char*)malloc(length); 
     174//              data_size = length; 
     175//              memcpy(data, event_data, length); 
     176//      } 
     177// 
     178//      // For the time being just make a string instead of an actual XmlElement object 
     179//      // At first there was going to be a general XmlElement object which the Event class 
     180//      // used as a base however it wasn't really needed ... for the time being 
     181//      std::wstring toXmlElement() 
     182//      { 
     183//              std::wstring document = L"<"; 
     184//              document += type; 
     185//              _ASSERT(false); 
     186// 
     187//              //stdext::hash_map<std::wstring, std::wstring>::iterator it; 
     188//              //for(it = attributes.begin(); it != attributes.end(); it++) 
     189//              //{ 
     190//              //      document += L" "; 
     191//              //      document += it->first; 
     192//              //      document += L"=\""; 
     193//              //      _ASSERT(false); 
     194//              //      //document += it->second->toString(); 
     195//              //      document += L"\""; 
     196//              //} 
     197// 
     198//              //document += L">"; 
     199// 
     200//              //if(child_events.size() > 0) 
     201//              //{ 
     202//              //      _ASSERT(data_size == 0); 
     203// 
     204//              //      std::vector<Event*>::iterator c_it; 
     205//              //      for(c_it = child_events.begin(); c_it != child_events.end(); c_it++) 
     206//              //      { 
     207//              //              document += (*it)->toXmlElement(); 
     208//              //      } 
     209//              //} 
     210// 
     211//              //if(data_size > 0) 
     212//              //{ 
     213//              //      _ASSERT(child_events.size() == 0); 
     214//              // 
     215//              //      document += data; 
     216//              //} 
     217// 
     218//              //document += L"</"; 
     219//              //document += name; 
     220//              //document += L">\r\n"; 
     221// 
     222//              return document; 
     223//      } 
     224// 
     225//      void addChildEvent(Event* e) 
     226//      { 
     227//              e->setParent(this); 
     228//              child_events.push_back(e); 
     229//      } 
     230// 
     231//      void setParent(Event* parent) 
     232//      { 
     233//              parent_event = parent; 
     234//      } 
     235// 
     236//      void setName(const std::wstring& name) 
     237//      { 
     238//              type = name; 
     239//      } 
     240// 
     241//      inline bool hasParent() { return (parent_event != NULL); } 
     242//      inline Event* getParent() { return parent_event; } 
     243//      inline std::wstring getName() { return type; } 
     244//      inline const std::vector<Event*>& getChildEvents() const { return child_events; } 
     245//      inline const stdext::hash_map<std::wstring, Variant*>& getAttributes() const { return attributes; } 
     246// 
     247//private: 
     248//      std::wstring type; 
     249//      stdext::hash_map<std::wstring, Variant*> attributes; 
     250// 
     251//      Event* parent_event; 
     252//      std::vector<Event*> child_events; 
     253//       
     254//      unsigned int data_size; 
     255//      char* data; 
     256//}; 
  • capture-hpc/branches/dev/capture-client/EventManager.cpp

    r352 r361  
    55 
    66 
    7 EventManager* EventManager::event_manager_instance = NULL; 
     7EventManager* EventManager::s_EventManager = NULL; 
    88 
    99struct EventData 
    1010{ 
    11         Event* e; 
     11        Element* e; 
    1212}; 
    1313 
     
    1515EventManager::getInstance() 
    1616{ 
    17         if(event_manager_instance == NULL) 
     17        if(s_EventManager == NULL) 
    1818        { 
    19                 event_manager_instance = new EventManager(); 
     19                s_EventManager = new EventManager(); 
    2020        } 
    21         return event_manager_instance; 
     21        return s_EventManager; 
    2222} 
    2323 
    2424EventManager::EventManager(void) 
    2525{ 
    26         event_router = new EventRouter<Event>(); 
    27         event_manager_thread = new Thread(this, false); 
    28         event_manager_thread->start(); 
     26        m_EventRouter = new EventRouter<Element>(); 
     27        m_EventManagerThread = new Thread(this); 
     28        m_EventManagerThread->start(); 
    2929} 
    3030 
    3131EventManager::~EventManager(void) 
    3232{ 
    33         event_manager_thread->stop(); 
    34         delete event_manager_thread; 
    35         delete event_router; 
     33        m_Running = false; 
     34 
     35        m_EventQueue.Clear(true); 
     36 
     37        m_EventManagerThread->stop(); 
     38        delete m_EventManagerThread; 
     39        delete m_EventRouter; 
    3640        LOG(INFO, "EventManager destroyed"); 
    3741} 
    3842 
    3943void 
    40 EventManager::queueEvent(Event* e) 
     44EventManager::queueEvent(Element* e) 
    4145{ 
    42         LOG(INFO, "EventManager: Queuing %ls event", e->getName().c_str()); 
    43         event_queue.push(e); 
     46        LOG(INFO, "EventManager: Queuing %ls event", e->GetName().c_str()); 
     47        m_EventQueue.Push(e); 
    4448} 
    4549 
     
    4751EventManager::run() 
    4852{ 
    49         while( running ) 
     53        bool valid = false; 
     54 
     55        while(m_Running) 
    5056        { 
    51                 if(!event_queue.empty()) 
    52                 { 
    53                         Event* e = event_queue.front(); 
    54                         event_queue.pop(); 
    55                         notify(e->getName(), *e); 
    56                         delete e; 
    57                 } else { 
    58                         Sleep(10); 
    59                 } 
     57                Element* e = NULL; 
     58 
     59                if(!m_EventQueue.Pop(e)) 
     60                        continue; 
     61 
     62                notify(e->GetName(), *e); 
     63 
     64                delete e; 
    6065        } 
    6166} 
     
    6368// Notify all object listening on a particular event of the message 
    6469void  
    65 EventManager::notify(const std::wstring& event_type, const Event& message) 
     70EventManager::notify(const std::wstring& eventType, const Element& message) 
    6671{ 
    67         LOG(INFO, "EventManager: Posting %ls event", event_type.c_str()); 
    68         event_router->notify(event_type, message); 
     72        LOG(INFO, "EventManager: Posting %ls event", eventType.c_str()); 
     73        m_EventRouter->notify(eventType, message); 
    6974} 
    7075 
     
    8186 
    8287void 
    83 EventManager::postEvent(const std::wstring& event_name, const Event& event) 
     88EventManager::postEvent(const std::wstring& event_name, const Element& event) 
    8489{ 
    8590        _ASSERT(false); // not implemented yet 
     
    8792 
    8893void 
    89 EventManager::startElement(void *user_data, const char* name, const char** attributes) 
     94EventManager::startElement(void *user_data, const wchar_t* name, const wchar_t** attributes) 
    9095{ 
    9196        EventData* event_data = (EventData*)user_data; 
    9297 
    93         std::wstring event_name = StringHelper::multiByteStringToWideString(name, strlen(name)+1); 
     98        //std::wstring event_name = StringHelper::multiByteStringToWideString(name, strlen(name)+1); 
     99        std::wstring event_name = name; 
    94100 
    95101        if(event_data->e) 
    96102        { 
    97                 if(event_data->e->getName().size() > 0 && event_data->e->getName() != event_name) 
     103                if(event_data->e->GetName().size() > 0 && event_data->e->GetName() != event_name) 
    98104                { 
    99                         Event* child_event = new Event(); 
    100                         event_data->e->addChildEvent(child_event); 
    101                         event_data->e = child_event; 
     105                        Element* childElement = new Element(); 
     106                        event_data->e->AddElement(childElement); 
     107                        event_data->e = childElement; 
    102108                } 
    103109        } 
    104110        else 
    105111        { 
    106                 event_data->e = new Event(); 
     112                event_data->e = new Element(); 
    107113        } 
    108114 
    109         event_data->e->setName(event_name); 
     115        event_data->e->SetName(event_name); 
    110116 
    111117        if (attributes) 
     
    117123                while(attributes[i] && attributes[i+1]) 
    118124                { 
    119                         attribute_name = StringHelper::multiByteStringToWideString(attributes[i], strlen(attributes[i])+1); 
    120                         attribute_value = StringHelper::multiByteStringToWideString(attributes[i+1], strlen(attributes[i+1])+1); 
     125                        //attribute_name = StringHelper::multiByteStringToWideString(attributes[i], strlen(attributes[i])+1); 
     126                        //attribute_value = StringHelper::multiByteStringToWideString(attributes[i+1], strlen(attributes[i+1])+1); 
     127                        attribute_name = attributes[i]; 
     128                        attribute_value = attributes[i+1]; 
    121129 
    122                         event_data->e->addAttribute(attribute_name, attribute_value); 
     130                        event_data->e->AddAttribute(attribute_name, attribute_value); 
    123131 
    124132                        i += 2; 
     
    128136 
    129137void 
    130 EventManager::endElement(void *user_data, const char* name) 
     138EventManager::endElement(void *user_data, const wchar_t* name) 
    131139{ 
    132140        EventData* event_data = (EventData*)user_data; 
     
    134142        _ASSERT(event_data->e); 
    135143 
    136         std::wstring event_name = StringHelper::multiByteStringToWideString(name, strlen(name)+1); 
     144        //std::wstring event_name = StringHelper::multiByteStringToWideString(name, strlen(name)+1); 
     145        std::wstring event_name = name; 
    137146 
    138147        // If we are back to the root event pass it onto the listeners else carry on 
    139         if(!event_data->e->hasParent()) 
     148        if(!event_data->e->HasParent()) 
    140149        { 
    141150                // Queue the event 
     
    145154        { 
    146155                // Go up the tree 
    147                 _ASSERT(event_data->e->getName() == event_name); // If assert is hit the XML is malformed 
    148                 event_data->e = event_data->e->getParent(); 
     156                _ASSERT(event_data->e->GetName() == event_name); // If assert is hit the XML is malformed 
     157                event_data->e = event_data->e->GetParent(); 
    149158        } 
    150159} 
     
    157166        Event* event = (*events->end()); 
    158167 
    159         event->setData(data, length); 
     168        //event->AddData(data, length); 
    160169} 
  • capture-hpc/branches/dev/capture-client/EventManager.h

    r352 r361  
    44#include "Event.h" 
    55#include "Thread.h" 
    6 #include <queue> 
     6#include "BlockingQueue.h" 
    77 
    88typedef void* EventConnection; 
     
    1515        void destroy() 
    1616        { 
    17                 if( event_manager_instance ) 
     17                if(s_EventManager) 
    1818                { 
    19                         delete event_manager_instance; 
     19                        delete s_EventManager; 
    2020                } 
    2121        } 
    2222 
    2323        template <typename ListenerT> 
    24         EventConnection attach(const std::wstring& event_type, ListenerT* event_listener, void (ListenerT::*member_function)(const std::wstring&, const Event&)) 
     24        EventConnection attach(const std::wstring& event_type, ListenerT* event_listener, void (ListenerT::*member_function)(const std::wstring&, const Element&)) 
    2525        { 
    26                 return event_router->attach<ListenerT>(event_type, event_listener, member_function); 
     26                return m_EventRouter->attach<ListenerT>(event_type, event_listener, member_function); 
    2727        } 
    2828 
    2929        void detach(EventConnection connection) 
    3030        { 
    31                 event_router->detach(connection); 
     31                m_EventRouter->detach(connection); 
    3232        }        
    3333 
    3434        void postEvent(const char* xml_event, unsigned int xml_event_length); 
    35         void postEvent(const std::wstring& event_name, const Event& event); 
     35        void postEvent(const std::wstring& event_name, const Element& event); 
    3636 
    3737private: 
    38         void startElement(void *user_data, const char* name, const char** attributes); 
    39         void endElement(void *user_data, const char* name); 
     38        void startElement(void *user_data, const wchar_t* name, const wchar_t** attributes); 
     39        void endElement(void *user_data, const wchar_t* name); 
    4040        void charData(void *user_data, const char* data, int length); 
    4141 
     
    4444        ~EventManager(void); 
    4545 
    46         void notify(const std::wstring& event_type, const Event& message); 
     46        void notify(const std::wstring& event_type, const Element& message); 
    4747         
    4848private: 
    4949        void run(); 
    50         void queueEvent(Event* e); 
    51         Thread* event_manager_thread; 
    52  
    53         std::queue<Event*> event_queue; 
     50        void queueEvent(Element* e); 
     51         
     52        Thread*                                         m_EventManagerThread; 
     53        EventRouter<Element>*                   m_EventRouter; 
     54        BlockingQueue<Element*, 256>    m_EventQueue; 
    5455 
    5556private: 
    56         static EventManager* event_manager_instance; 
    57         EventRouter<Event>* event_router; 
     57        static EventManager*    s_EventManager; 
     58         
    5859}; 
  • capture-hpc/branches/dev/capture-client/Exclusion.cpp

    r352 r361  
    6767        allow = false; 
    6868 
     69        // Remove whitespace from the start and end of the string 
     70        // "^[ \t]+|[ \t]+$" 
     71 
     72        // Validate the string to make sure it is a valid exclusion entry 
     73        // "^(-+)+\t+[A-Z0-9]+[^\t]+$" 
     74 
    6975        do 
    7076        { 
  • capture-hpc/branches/dev/capture-client/ExclusionList.h

    r352 r361  
    1414 
    1515        void addExclusion(const std::wstring& type, const std::wstring& exclusion, bool permaneant); 
    16         void onExclusionReceived(const std::wstring& event_type, const Event& event) 
     16        void onExclusionReceived(const std::wstring& event_type, const Element& e) 
    1717        { 
    1818        } 
  • capture-hpc/branches/dev/capture-client/Expat.cpp

    r352 r361  
    2323        XML_SetUserData(parser, parser_information); 
    2424 
    25         XML_SetElementHandler(parser, startElement, endElement); 
     25        XML_SetElementHandler(parser, (XML_StartElementHandler)startElement, (XML_EndElementHandler)endElement); 
    2626 
    2727        parser_status = XML_Parse(parser, document, document_length, 1); 
     
    3333 
    3434void  
    35 Expat::startElement(void *user_data, const XML_Char *name, const XML_Char **attributes) 
     35Expat::startElement(void *user_data, const wchar_t* name, const wchar_t** attributes) 
    3636{ 
    3737        ParserInformation* parser_information = (ParserInformation*)user_data; 
     
    4343 
    4444void 
    45 Expat::endElement(void *user_data, const XML_Char *name) 
     45Expat::endElement(void *user_data, const wchar_t* name) 
    4646{ 
    4747        ParserInformation* parser_information = (ParserInformation*)user_data; 
  • capture-hpc/branches/dev/capture-client/Expat.h

    r352 r361  
    1111 
    1212private: 
    13         static void startElement(void *user_data, const XML_Char *name, const XML_Char **attributes); 
    14         static void endElement(void *user_data, const XML_Char *name); 
     13        static void startElement(void *user_data, const wchar_t* name, const wchar_t** attributes); 
     14        static void endElement(void *user_data, const wchar_t* name); 
    1515        static void charData(void *user_data, const char *data, int length); 
    1616}; 
  • capture-hpc/branches/dev/capture-client/KernelDrivers/CaptureKernelDrivers/CaptureKernelDrivers.vcproj

    r360 r361  
    8888                                > 
    8989                        </File> 
     90                        <File 
     91                                RelativePath=".\FileMonitor\CaptureFileMonitor.h" 
     92                                > 
     93                        </File> 
    9094                </Filter> 
    9195                <Filter 
     
    105109                        </File> 
    106110                </Filter> 
     111                <Filter 
     112                        Name="NetworkMonitor" 
     113                        > 
     114                        <File 
     115                                RelativePath=".\NetworkMonitor\CaptureConnectionMonitor.c" 
     116                                > 
     117                        </File> 
     118                </Filter> 
    107119        </Files> 
    108120        <Globals> 
  • capture-hpc/branches/dev/capture-client/KernelDrivers/CaptureKernelDrivers/FileMonitor/CaptureFileMonitor.c

    r194 r361  
    2222 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA 
    2323 */ 
    24 //#define WINVER _WIN32_WINNT_WINXP 
    25 //#define _WIN32_WINNT 0x0502 
    26 //#define _WIN32_WINNT _WIN32_WINNT_WINXP 
    27 //#define NTDDI_VERSION NTDDI_WINXPSP2 
    28 //#define FLT_MGR_BASELINEd 
    29 #define NTDDI_WINXPSP2                      0x05010200 
    30 #define OSVERSION_MASK      0xFFFF0000 
    31 #define SPVERSION_MASK      0x0000FF00 
    32 #define SUBVERSION_MASK     0x000000FF 
    33  
    34  
    35 // 
    36 // macros to extract various version fields from the NTDDI version 
    37 // 
    38 #define OSVER(Version)  ((Version) & OSVERSION_MASK) 
    39 #define SPVER(Version)  (((Version) & SPVERSION_MASK) >> 8) 
    40 #define SUBVER(Version) (((Version) & SUBVERSION_MASK) ) 
    41 //#define NTDDI_VERSION   NTDDI_WINXPSP2 
    42 //#include <sdkddkver.h> 
    43 #include <ntifs.h> 
    44 #include <wdm.h> 
    45 //#include <ntddk.h> 
    46  
    47 #include <fltkernel.h> 
    48 #include <ntstrsafe.h> 
    49  
    50 typedef unsigned int UINT; 
    51  
    52 #define FILE_DEVICE_UNKNOWN             0x00000022 
    53 #define IOCTL_UNKNOWN_BASE              FILE_DEVICE_UNKNOWN 
    54 #define IOCTL_CAPTURE_GET_FILEEVENTS      CTL_CODE(FILE_DEVICE_UNKNOWN, 0x804, METHOD_NEITHER,FILE_READ_DATA | FILE_WRITE_DATA) 
    55 #define CAPTURE_FILEMON_PORT_NAME                   L"\\CaptureFileMonitorPort" 
    56 #define USERSPACE_CONNECTION_TIMEOUT 10 
    57 #define FILE_POOL_TAG 'cfm' 
    58 #define FILE_PACKET_POOL_TAG 'cfmP' 
    59 #define FILE_EVENT_POOL_TAG 'cfmE' 
    60  
    61 /* Naughty ... The following 2 definitions are not documented functions or structures so may 
    62    change at any time */ 
    63 typedef struct _THREAD_BASIC_INFORMATION {  
    64         NTSTATUS ExitStatus;  
    65         PVOID TebBaseAddress;  
    66         ULONG UniqueProcessId;  
    67         ULONG UniqueThreadId;  
    68         KAFFINITY AffinityMask;  
    69         KPRIORITY BasePriority;  
    70         ULONG DiffProcessPriority;  
    71 } THREAD_BASIC_INFORMATION, *PTHREAD_BASIC_INFORMATION; 
    72  
    73 NTSYSAPI NTSTATUS NTAPI ZwQueryInformationThread (IN HANDLE ThreadHandle,  
    74                                                                                                   IN THREADINFOCLASS ThreadInformationClass,  
    75                                                                                                   OUT PVOID ThreadInformation,  
    76                                                                                                   IN ULONG ThreadInformationLength,  
    77                                                                                                   OUT PULONG ReturnLength OPTIONAL ); 
    78  
    79 FLT_POSTOP_CALLBACK_STATUS PostFileOperationCallback ( IN OUT PFLT_CALLBACK_DATA Data,  
    80                                 IN PCFLT_RELATED_OBJECTS FltObjects,  
    81                                 IN PVOID CompletionContext,  
    82                                 IN FLT_POST_OPERATION_FLAGS Flags); 
    83                                  
    84 FLT_PREOP_CALLBACK_STATUS 
    85 PreFileOperationCallback ( 
    86     __inout PFLT_CALLBACK_DATA Data, 
    87     __in PCFLT_RELATED_OBJECTS FltObjects, 
    88     __deref_out_opt PVOID *CompletionContext 
    89     ); 
    90  
    91 NTSTATUS FilterUnload ( IN FLT_FILTER_UNLOAD_FLAGS Flags ); 
    92  
    93 NTSTATUS SetupCallback (IN PCFLT_RELATED_OBJECTS  FltObjects, 
    94                                 IN FLT_INSTANCE_SETUP_FLAGS  Flags, 
    95                                 IN DEVICE_TYPE  VolumeDeviceType, 
    96                                 IN FLT_FILESYSTEM_TYPE  VolumeFilesystemType); 
    97  
    98 NTSTATUS MessageCallback ( 
    99     __in PVOID ConnectionCookie, 
    100     __in_bcount_opt(InputBufferSize) PVOID InputBuffer, 
    101     __in ULONG InputBufferSize, 
    102     __out_bcount_part_opt(OutputBufferSize,*ReturnOutputBufferLength) PVOID OutputBuffer, 
    103     __in ULONG OutputBufferSize, 
    104     __out PULONG ReturnOutputBufferLength 
    105     ); 
    106  
    107 NTSTATUS ConnectCallback( 
    108     __in PFLT_PORT ClientPort, 
    109     __in PVOID ServerPortCookie, 
    110     __in_bcount(SizeOfContext) PVOID ConnectionContext, 
    111     __in ULONG SizeOfContext, 
    112     __deref_out_opt PVOID *ConnectionCookie 
    113     ); 
    114  
    115 VOID DisconnectCallback( 
    116     __in_opt PVOID ConnectionCookie 
    117     ); 
    118 // Callback that this driver will be listening for. This is sent to the filter manager 
    119 // where it is registered 
    120 CONST FLT_OPERATION_REGISTRATION Callbacks[] = { 
    121          
    122     { IRP_MJ_CREATE, 
    123       0, 
    124       PreFileOperationCallback, 
    125       PostFileOperationCallback }, 
    126  
    127     { IRP_MJ_CREATE_NAMED_PIPE, 
    128       0, 
    129       PreFileOperationCallback, 
    130       PostFileOperationCallback }, 
    131  
    132     { IRP_MJ_CLOSE, 
    133       0, 
    134       PreFileOperationCallback, 
    135       PostFileOperationCallback }, 
    136  
    137     { IRP_MJ_READ, 
    138       0, 
    139       PreFileOperationCallback, 
    140       PostFileOperationCallback }, 
    141  
    142     { IRP_MJ_WRITE, 
    143       0, 
    144       PreFileOperationCallback, 
    145       PostFileOperationCallback }, 
    146  
    147     { IRP_MJ_QUERY_INFORMATION, 
    148       0, 
    149       PreFileOperationCallback, 
    150       PostFileOperationCallback }, 
    151  
    152     { IRP_MJ_SET_INFORMATION, 
    153       0, 
    154       PreFileOperationCallback, 
    155       PostFileOperationCallback }, 
    156  
    157     { IRP_MJ_QUERY_EA, 
    158       0, 
    159       PreFileOperationCallback, 
    160       PostFileOperationCallback }, 
    161  
    162     { IRP_MJ_SET_EA, 
    163       0, 
    164       PreFileOperationCallback, 
    165       PostFileOperationCallback }, 
    166  
    167     { IRP_MJ_FLUSH_BUFFERS, 
    168       0, 
    169       PreFileOperationCallback, 
    170       PostFileOperationCallback }, 
    171  
    172     { IRP_MJ_QUERY_VOLUME_INFORMATION, 
    173       0, 
    174       PreFileOperationCallback, 
    175       PostFileOperationCallback }, 
    176  
    177     { IRP_MJ_SET_VOLUME_INFORMATION, 
    178       0, 
    179       PreFileOperationCallback, 
    180       PostFileOperationCallback }, 
    181  
    182     { IRP_MJ_DIRECTORY_CONTROL, 
    183       0, 
    184       PreFileOperationCallback, 
    185       PostFileOperationCallback }, 
    186  
    187     { IRP_MJ_FILE_SYSTEM_CONTROL, 
    188       0, 
    189       PreFileOperationCallback, 
    190       PostFileOperationCallback }, 
    191  
    192     { IRP_MJ_DEVICE_CONTROL, 
    193       0, 
    194       PreFileOperationCallback, 
    195       PostFileOperationCallback }, 
    196  
    197     { IRP_MJ_INTERNAL_DEVICE_CONTROL, 
    198       0, 
    199       PreFileOperationCallback, 
    200       PostFileOperationCallback }, 
    201  
    202     { IRP_MJ_SHUTDOWN, 
    203       0, 
    204       PreFileOperationCallback, 
    205       NULL }, 
    206  
    207     { IRP_MJ_LOCK_CONTROL, 
    208       0, 
    209       PreFileOperationCallback, 
    210       PostFileOperationCallback }, 
    211  
    212     { IRP_MJ_CLEANUP, 
    213       0, 
    214       PreFileOperationCallback, 
    215       PostFileOperationCallback }, 
    216  
    217     { IRP_MJ_CREATE_MAILSLOT, 
    218       0, 
    219       PreFileOperationCallback, 
    220       PostFileOperationCallback }, 
    221  
    222     { IRP_MJ_QUERY_SECURITY, 
    223       0, 
    224       PreFileOperationCallback, 
    225       PostFileOperationCallback }, 
    226  
    227     { IRP_MJ_SET_SECURITY, 
    228       0, 
    229       PreFileOperationCallback, 
    230       PostFileOperationCallback }, 
    231  
    232     { IRP_MJ_QUERY_QUOTA, 
    233       0, 
    234       PreFileOperationCallback, 
    235       PostFileOperationCallback }, 
    236  
    237     { IRP_MJ_SET_QUOTA, 
    238       0, 
    239       PreFileOperationCallback, 
    240       PostFileOperationCallback }, 
    241  
    242     { IRP_MJ_PNP, 
    243       0, 
    244       PreFileOperationCallback, 
    245       PostFileOperationCallback }, 
    246  
    247     { IRP_MJ_ACQUIRE_FOR_SECTION_SYNCHRONIZATION, 
    248       0, 
    249       PreFileOperationCallback, 
    250       PostFileOperationCallback }, 
    251  
    252     { IRP_MJ_RELEASE_FOR_SECTION_SYNCHRONIZATION, 
    253       0, 
    254       PreFileOperationCallback, 
    255       PostFileOperationCallback }, 
    256  
    257     { IRP_MJ_ACQUIRE_FOR_MOD_WRITE, 
    258       0, 
    259       PreFileOperationCallback, 
    260       PostFileOperationCallback }, 
    261  
    262     { IRP_MJ_RELEASE_FOR_MOD_WRITE, 
    263       0, 
    264       PreFileOperationCallback, 
    265       PostFileOperationCallback }, 
    266  
    267     { IRP_MJ_ACQUIRE_FOR_CC_FLUSH, 
    268       0, 
    269       PreFileOperationCallback, 
    270       PostFileOperationCallback }, 
    271  
    272     { IRP_MJ_RELEASE_FOR_CC_FLUSH, 
    273       0, 
    274       PreFileOperationCallback, 
    275       PostFileOperationCallback }, 
    276  
    277     { IRP_MJ_FAST_IO_CHECK_IF_POSSIBLE, 
    278       0, 
    279       PreFileOperationCallback, 
    280       PostFileOperationCallback }, 
    281  
    282     { IRP_MJ_NETWORK_QUERY_OPEN, 
    283       0, 
    284       PreFileOperationCallback, 
    285       PostFileOperationCallback }, 
    286  
    287     { IRP_MJ_MDL_READ, 
    288       0, 
    289       PreFileOperationCallback, 
    290       PostFileOperationCallback }, 
    291  
    292     { IRP_MJ_MDL_READ_COMPLETE, 
    293       0, 
    294       PreFileOperationCallback, 
    295       PostFileOperationCallback }, 
    296  
    297     { IRP_MJ_PREPARE_MDL_WRITE, 
    298       0, 
    299       PreFileOperationCallback, 
    300       PostFileOperationCallback }, 
    301  
    302     { IRP_MJ_MDL_WRITE_COMPLETE, 
    303       0, 
    304       PreFileOperationCallback, 
    305       PostFileOperationCallback }, 
    306  
    307     { IRP_MJ_VOLUME_MOUNT, 
    308       0, 
    309       PreFileOperationCallback, 
    310       PostFileOperationCallback }, 
    311  
    312     { IRP_MJ_VOLUME_DISMOUNT, 
    313       0, 
    314       PreFileOperationCallback, 
    315       PostFileOperationCallback }, 
    316  
    317     { IRP_MJ_OPERATION_END } 
    318 }; 
    319  
    320 /* File event */ 
    321 typedef struct  _FILE_EVENT { 
    322         UCHAR majorFileEventType; 
    323         UCHAR minorFileEventType; 
     24#include "CaptureFileMonitor.h" 
     25 
     26static unsigned int process_id_hash; 
     27static unsigned int file_name_hash; 
     28 
     29#define IS_CREATE_OPERATION(data)               (data->Iopb->MajorFunction == IRP_MJ_CREATE)     
     30#define IS_RENAME_OPERATION(data)               (data->Iopb->MajorFunction == IRP_MJ_SET_INFORMATION &&         \ 
     31                                                                                        data->Iopb->Parameters.SetFileInformation.FileInformationClass == FileRenameInformation) 
     32#define IS_DELETE_OPERATION(data)               (data->Iopb->MajorFunction == IRP_MJ_SET_INFORMATION &&         \ 
     33                                                                                        data->Iopb->Parameters.SetFileInformation.FileInformationClass == FileDispositionInformation && \ 
     34                                                                                        (PFILE_DISPOSITION_INFORMATION)data->Iopb->Parameters.SetFileInformation.InfoBuffer->DeleteFile) 
     35#define IS_HARDLINK_OPERATION(data)             (data->Iopb->MajorFunction == IRP_MJ_SET_INFORMATION &&         \ 
     36                                                                                        data->Iopb->Parameters.SetFileInformation.FileInformationClass == FileLinkInformation) 
     37 
     38 
     39// Main entry point into the driver, is called when the driver is loaded 
     40NTSTATUS DriverEntry( 
     41        IN PDRIVER_OBJECT driver_object,  
     42        IN PUNICODE_STRING registry_path 
     43        ) 
     44{ 
    32445        NTSTATUS status; 
    325         ULONG information; 
    326         ULONG flags; 
    327         TIME_FIELDS time; 
    328         HANDLE processId; 
    329         UINT filePathLength; 
    330         WCHAR filePath[]; 
    331 } FILE_EVENT, *PFILE_EVENT; 
    332  
    333 /* Storage for file event to be put into a linked list */ 
    334 typedef struct  _FILE_EVENT_PACKET { 
    335     LIST_ENTRY Link; 
    336         PFILE_EVENT pFileEvent; 
    337 } FILE_EVENT_PACKET, * PFILE_EVENT_PACKET;  
    338  
    339 typedef enum _FILEMONITOR_COMMAND { 
    340     GetFileEvents, 
    341         SetupMonitor 
    342 } FILEMONITOR_COMMAND; 
    343  
    344 typedef struct _FILEMONITOR_SETUP { 
    345         BOOLEAN bCollectDeletedFiles; 
    346         INT nLogDirectorySize; 
    347         WCHAR wszLogDirectory[1024]; 
    348 } FILEMONITOR_SETUP, *PFILEMONITOR_SETUP; 
    349  
    350 typedef struct _FILEMONITOR_MESSAGE { 
    351     FILEMONITOR_COMMAND Command; 
    352 } FILEMONITOR_MESSAGE, *PFILEMONITOR_MESSAGE; 
    353  
    354  
    355 const FLT_CONTEXT_REGISTRATION Contexts[] = { 
    356     { FLT_CONTEXT_END } 
    357 }; 
    358  
    359 CONST FLT_REGISTRATION FilterRegistration = { 
    360     sizeof(FLT_REGISTRATION), 
    361     FLT_REGISTRATION_VERSION, 
    362     0, 
    363     Contexts, 
    364     Callbacks, 
    365     FilterUnload, 
    366     SetupCallback, 
    367     NULL, 
    368     NULL, 
    369     NULL, 
    370     NULL, 
    371     NULL, 
    372     NULL 
    373 }; 
    374  
    375 typedef struct _CAPTURE_FILE_MANAGER 
    376 { 
    377         PDRIVER_OBJECT pDriverObject; 
    378         PFLT_FILTER pFilter; 
    379         PFLT_PORT pServerPort; 
    380         PFLT_PORT pClientPort; 
    381         LIST_ENTRY lQueuedFileEvents; 
    382         KSPIN_LOCK  lQueuedFileEventsSpinLock; 
    383         KTIMER connectionCheckerTimer; 
    384         KDPC connectionCheckerFunction; 
    385         BOOLEAN bReady; 
    386         BOOLEAN bCollectDeletedFiles; 
    387         UNICODE_STRING logDirectory; 
    388         ULONG lastContactTime; 
    389 } CAPTURE_FILE_MANAGER, *PCAPTURE_FILE_MANAGER; 
    390  
    391  
    392 BOOLEAN QueueFileEvent(PFILE_EVENT pFileEvent); 
    393 VOID UpdateLastContactTime(); 
    394 ULONG GetCurrentTime(); 
    395 VOID ConnectionChecker( 
    396     IN struct _KDPC  *Dpc, 
    397     IN PVOID  DeferredContext, 
    398     IN PVOID  SystemArgument1, 
    399     IN PVOID  SystemArgument2 
    400     ); 
    401 VOID DeferredCopyFunction(IN PFLT_DEFERRED_IO_WORKITEM WorkItem,  
    402                                          IN PFLT_CALLBACK_DATA CallbackData,  
    403                                          IN PVOID CompletionContext); 
    404 NTSTATUS CopyFile( 
    405                  PFLT_CALLBACK_DATA Data, 
    406                  PCFLT_RELATED_OBJECTS FltObjects, 
    407                  PUNICODE_STRING pCompleteFileName 
    408                  ); 
    409 VOID 
    410 GetDosDeviceName(PDEVICE_OBJECT pDeviceObject, 
    411                                  PUNICODE_STRING pShareName, 
    412                                  PUNICODE_STRING pDosName); 
    413 VOID CreateADirectory(PFLT_INSTANCE pInstance,  
    414                                 PUNICODE_STRING pDirectoryPath); 
    415 VOID CreateAllDirectories(PFLT_INSTANCE pInstance, PUNICODE_STRING pRootDirectory, PUNICODE_STRING directory); 
    416 /* Global variables */ 
    417 CAPTURE_FILE_MANAGER fileManager; 
    418 BOOLEAN busy; 
    419  
    420 /*      Main entry point into the driver, is called when the driver is loaded */ 
    421 NTSTATUS DriverEntry( 
    422         IN PDRIVER_OBJECT DriverObject,  
    423         IN PUNICODE_STRING RegistryPath 
    424         ) 
    425 { 
    426         NTSTATUS status; 
    427         OBJECT_ATTRIBUTES objectAttributes; 
    428         PSECURITY_DESCRIPTOR pSecurityDescriptor; 
    429         UNICODE_STRING fileMonitorPortName; 
    430         LARGE_INTEGER fileEventsTimeout; 
    431         busy = FALSE; 
    432         fileManager.bReady = FALSE; 
    433         fileManager.bCollectDeletedFiles = FALSE; 
    434         KeInitializeSpinLock(&fileManager.lQueuedFileEventsSpinLock); 
    435         InitializeListHead(&fileManager.lQueuedFileEvents); 
    436         fileManager.pDriverObject = DriverObject; 
    437         //fileManager.logDirectory.Buffer = NULL; 
    438  
    439         /* Register driver with the filter manager */ 
    440         status = FltRegisterFilter(DriverObject, &FilterRegistration, &fileManager.pFilter); 
     46        UNICODE_STRING port_name; 
     47        OBJECT_ATTRIBUTES object_attributes; 
     48        PSECURITY_DESCRIPTOR security_descriptor; 
     49 
     50        const FLT_REGISTRATION filter_registration = { 
     51                sizeof(FLT_REGISTRATION), 
     52                FLT_REGISTRATION_VERSION, 
     53                0, 
     54                filter_contexts, 
     55                file_event_callbacks, 
     56                FilterUnload, 
     57                FilterSetup, 
     58                NULL, 
     59                NULL, 
     60                NULL, 
     61                NULL, 
     62                NULL, 
     63                NULL 
     64        }; 
     65 
     66        // Register driver with the filter manager 
     67        status = FltRegisterFilter(driver_object, &filter_registration, &file_manager.filter); 
    44168 
    44269        if (!NT_SUCCESS(status)) 
     
    44673        } 
    44774 
    448         status  = FltBuildDefaultSecurityDescriptor( &pSecurityDescriptor, FLT_PORT_ALL_ACCESS ); 
    449  
    450         if (!NT_SUCCESS(status)) 
    451         { 
    452                 DbgPrint("CaptureFileMonitor: ERROR FltBuildDefaultSecurityDescriptor - %08x\n", status); 
    453                 return status; 
    454         } 
    455  
    456         RtlInitUnicodeString( &fileMonitorPortName, CAPTURE_FILEMON_PORT_NAME ); 
    457         InitializeObjectAttributes( &objectAttributes, 
    458                                                                 &fileMonitorPortName, 
    459                                                                 OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, 
    460                                                                 NULL, 
    461                                                                 pSecurityDescriptor); 
    462  
    463         /* Create the communications port to communicate with the user space process (pipe) */ 
    464         status = FltCreateCommunicationPort( fileManager.pFilter, 
    465                                              &fileManager.pServerPort, 
    466                                              &objectAttributes, 
    467                                              NULL, 
    468                                              ConnectCallback, 
    469                                              DisconnectCallback, 
    470                                              MessageCallback, 
    471                                              1 ); 
    472  
    473         FltFreeSecurityDescriptor(pSecurityDescriptor); 
    474  
    475         /* Start the filtering */ 
     75        //status = FltBuildDefaultSecurityDescriptor(&security_descriptor, FLT_PORT_ALL_ACCESS); 
     76 
     77        //if (!NT_SUCCESS(status)) 
     78        //{ 
     79        //      DbgPrint("CaptureFileMonitor: ERROR FltBuildDefaultSecurityDescriptor - %08x\n", status); 
     80        //      FltUnregisterFilter(file_manager.filter); 
     81        //      return status; 
     82        //} 
     83 
     84        //RtlInitUnicodeString( &port_name, FILEMONITOR_PORTNAME ); 
     85        //InitializeObjectAttributes( &object_attributes, 
     86        //                                                      &port_name, 
     87        //                                                      OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, 
     88        //                                                      NULL, 
     89        //                                                      security_descriptor); 
     90 
     91        //// Create the communication port 
     92        //status = FltCreateCommunicationPort(file_manager.filter, 
     93        //                                                                      &file_manager.server_port, 
     94        //                                                                      &object_attributes, 
     95        //                                                                      NULL, 
     96        //                                                                      ConnectCallback, 
     97        //                                                                      DisconnectCallback, 
     98        //                                                                      MessageCallback, 
     99        //                                                                      1); 
     100        //FltFreeSecurityDescriptor(security_descriptor); 
     101 
     102        // Initialise the event ring buffer 
     103        InitialiseEventRingList(&file_manager.event_ring_list, 512*1024, 4, 128*1024, 128, 16 ); 
     104 
     105        file_name_hash = AddKey(&file_manager.event_ring_list, "file-path"); 
     106        process_id_hash = AddKey(&file_manager.event_ring_list, "process-id"); 
     107 
     108        // Start the filtering 
    476109        if(NT_SUCCESS(status)) 
    477110        { 
    478                 status = FltStartFiltering(fileManager.pFilter); 
     111                status = FltStartFiltering(file_manager.filter); 
    479112                if(!NT_SUCCESS(status)) 
    480113                { 
     
    485118        } 
    486119 
    487         /* If there was a problem during initialisation of the filter then uninstall everything */ 
     120        // Cleanup everything if there was error during initialisation 
    488121        if(!NT_SUCCESS(status)) 
    489122        { 
    490                 if (fileManager.pServerPort != NULL) 
    491                         FltCloseCommunicationPort(fileManager.pServerPort); 
    492                 if (fileManager.pFilter != NULL) 
    493                         FltUnregisterFilter(fileManager.pFilter); 
    494                 return status; 
    495         } 
    496  
    497         UpdateLastContactTime(); 
    498  
    499         /* Create a DPC routine so that it can be called periodically */ 
    500         KeInitializeDpc(&fileManager.connectionCheckerFunction,  
    501                 (PKDEFERRED_ROUTINE)ConnectionChecker, &fileManager); 
    502         KeInitializeTimer(&fileManager.connectionCheckerTimer); 
    503         fileEventsTimeout.QuadPart = 0; 
    504  
    505         /* Set the ConnectionChecker routine to be called every so often */ 
    506         KeSetTimerEx(&fileManager.connectionCheckerTimer,  
    507                 fileEventsTimeout,  
    508                 (USERSPACE_CONNECTION_TIMEOUT+(USERSPACE_CONNECTION_TIMEOUT/2))*1000,  
    509                 &fileManager.connectionCheckerFunction); 
    510  
    511         fileManager.bReady = TRUE; 
    512         fileManager.logDirectory.Length = 0; 
    513         fileManager.logDirectory.Buffer = NULL; 
     123                if (file_manager.server_port != NULL) 
     124                        FltCloseCommunicationPort(file_manager.server_port); 
     125                if (file_manager.filter != NULL) 
     126                        FltUnregisterFilter(file_manager.filter); 
     127        } 
     128 
    514129        DbgPrint("CaptureFileMonitor: Successfully Loaded\n"); 
    515130 
    516         return STATUS_SUCCESS; 
    517 } 
    518  
    519 VOID FreeQueuedEvents() 
    520 { 
    521         while(!IsListEmpty(&fileManager.lQueuedFileEvents)) 
    522         { 
    523                 PLIST_ENTRY head = ExInterlockedRemoveHeadList(&fileManager.lQueuedFileEvents, &fileManager.lQueuedFileEventsSpinLock); 
    524                 PFILE_EVENT_PACKET pFileEventPacket = CONTAINING_RECORD(head, FILE_EVENT_PACKET, Link); 
    525                 ExFreePoolWithTag(pFileEventPacket->pFileEvent, FILE_POOL_TAG); 
    526                 ExFreePoolWithTag(pFileEventPacket, FILE_POOL_TAG); 
    527         } 
    528 } 
    529  
    530 /* Checks to see if the file monitor has received an IOCTL from a userspace 
    531    program in a while. If it hasn't then all old queued file events are 
    532    cleared. This is called periodically when the driver is loaded */ 
    533 VOID ConnectionChecker( 
    534     IN struct _KDPC  *Dpc, 
    535     IN PVOID  DeferredContext, 
    536     IN PVOID  SystemArgument1, 
    537     IN PVOID  SystemArgument2 
     131        return status; 
     132} 
     133 
     134NTSTATUS FilterSetup( 
     135        PCFLT_RELATED_OBJECTS  filter_objects, 
     136        FLT_INSTANCE_SETUP_FLAGS  flags, 
     137        DEVICE_TYPE  volume_device_type, 
     138        FLT_FILESYSTEM_TYPE  volume_file_system_type 
    538139    ) 
    539140{ 
    540         if(     (GetCurrentTime()-fileManager.lastContactTime) > (USERSPACE_CONNECTION_TIMEOUT+(USERSPACE_CONNECTION_TIMEOUT/2))) 
    541         { 
    542                 DbgPrint("CaptureFileMonitor: WARNING Userspace IOCTL timeout, clearing old queued registry events\n"); 
    543                 FreeQueuedEvents(); 
    544         } 
    545 } 
    546  
    547  
    548  
    549 NTSTATUS 
    550 CopyFile( 
    551                  PFLT_CALLBACK_DATA Data, 
    552                  PCFLT_RELATED_OBJECTS FltObjects, 
    553                  PUNICODE_STRING pCompleteFileName 
    554                  ) 
    555 { 
    556141        NTSTATUS status; 
    557         UNICODE_STRING tempDeletedFilePath; 
    558         OBJECT_ATTRIBUTES tempDeletedObject; 
    559         IO_STATUS_BLOCK ioStatusTempDeleted; 
    560         LARGE_INTEGER allocate; 
    561         FILE_STANDARD_INFORMATION fileStandardInformation; 
    562         HANDLE tempDeletedHandle; 
    563         ULONG returnedLength; 
    564         allocate.QuadPart = 0x10000; 
    565  
    566          
    567          
    568         InitializeObjectAttributes( 
    569                 &tempDeletedObject, 
    570                 pCompleteFileName, 
    571                 OBJ_CASE_INSENSITIVE, 
    572                 NULL, 
    573                 NULL 
    574                 ); 
    575         status = FltQueryInformationFile( 
    576                 FltObjects->Instance, 
    577                 Data->Iopb->TargetFileObject, 
    578                 &fileStandardInformation, 
    579                 sizeof(FILE_STANDARD_INFORMATION), 
    580                 FileStandardInformation, 
    581                 &returnedLength 
    582                 ); 
    583         if(NT_SUCCESS(status)) 
    584         { 
    585                 allocate.QuadPart = fileStandardInformation.AllocationSize.QuadPart; 
    586         } else { 
    587                 DbgPrint("CaptureFileMonitor: ERROR - Could not get files allocation size\n"); 
    588                 return status; 
    589         } 
    590  
    591         status = FltCreateFile( 
    592                 FltObjects->Filter, 
    593                 NULL, 
    594                 &tempDeletedHandle, 
    595                 GENERIC_WRITE, 
    596                 &tempDeletedObject, 
    597                 &ioStatusTempDeleted, 
    598                 &allocate, 
    599                 FILE_ATTRIBUTE_NORMAL, 
    600                 0, 
    601                 FILE_CREATE, 
    602                 FILE_NON_DIRECTORY_FILE, 
    603                 NULL, 
    604                 0, 
    605                 0 
    606                 ); 
    607  
    608         if(NT_SUCCESS(status)) 
    609         { 
    610                 PVOID handleFileObject; 
    611                 PVOID pFileBuffer; 
    612                 LARGE_INTEGER offset; 
    613          
    614                 ULONG bytesRead = 0; 
    615                 ULONG bytesWritten = 0; 
    616                 offset.QuadPart = 0; 
    617                 status = ObReferenceObjectByHandle( 
    618                         tempDeletedHandle, 
    619                         0, 
    620                         NULL, 
    621                         KernelMode, 
    622                         &handleFileObject, 
    623                         NULL); 
    624                 if(!NT_SUCCESS(status)) 
    625                 { 
    626                         DbgPrint("CaptureFileMonitor: ERROR - ObReferenceObjectByHandle - FAILED - %08x\n", status); 
    627                         return status; 
    628                 } 
    629                  
    630                 pFileBuffer = ExAllocatePoolWithTag(NonPagedPool, 65536, FILE_POOL_TAG); 
    631                  
    632                 if(pFileBuffer != NULL) 
    633                 { 
    634                         ObReferenceObject(Data->Iopb->TargetFileObject); 
    635                         do { 
    636                                 IO_STATUS_BLOCK IoStatusBlock; 
    637                                 bytesWritten = 0; 
    638                                 status = FltReadFile( 
    639                                         FltObjects->Instance, 
    640                                         Data->Iopb->TargetFileObject, 
    641                                         &offset, 
    642                                         65536, 
    643                                         pFileBuffer, 
    644                                         FLTFL_IO_OPERATION_DO_NOT_UPDATE_BYTE_OFFSET, 
    645                                         &bytesRead , 
    646                                         NULL, 
    647                                         NULL 
    648                                         ); 
    649                          
    650                                 if(NT_SUCCESS(status) && bytesRead > 0) 
    651                                 { 
    652                                         /* You can't use FltWriteFile here */ 
    653                                         /* Instance may not be the same instance we want to write to eg a 
    654                                            flash drive writing a file to a ntfs partition */ 
    655                                         status = ZwWriteFile( 
    656                                                 tempDeletedHandle, 
    657                                                 NULL, 
    658                                                 NULL, 
    659                                                 NULL, 
    660                                                 &IoStatusBlock, 
    661                                                 pFileBuffer, 
    662                                                 bytesRead, 
    663                                                 &offset, 
    664                                                 NULL 
    665                                                 ); 
    666                                         if(NT_SUCCESS(status)) 
    667                                         { 
    668                                                 //DbgPrint("WriteFile: FltReadFile - %08x\n", status); 
    669                                         } 
    670                                         /* 
    671                                         status = FltWriteFile( 
    672                                                 FltObjects->Instance, 
    673                                                 handleFileObject, 
    674                                                 &offset, 
    675                                                 bytesRead, 
    676                                                 pFileBuffer, 
    677                                                 FLTFL_IO_OPERATION_DO_NOT_UPDATE_BYTE_OFFSET, 
    678                                                 &bytesWritten, 
    679                                                 NULL, 
    680                                                 NULL 
    681                                                 ); 
    682                                                 */ 
    683                                 } else { 
    684                                         //DbgPrint("CopyFile: FltReadFile - %08x\n", status); 
    685                                         break; 
    686                                 } 
    687                                 offset.QuadPart += bytesRead; 
    688                         } while(bytesRead == 65536); 
    689                         ObDereferenceObject(Data->Iopb->TargetFileObject); 
    690                         ExFreePoolWithTag(pFileBuffer, FILE_POOL_TAG); 
    691                 } 
    692                 ObDereferenceObject(handleFileObject); 
    693                 FltClose(tempDeletedHandle); 
    694         } else { 
    695                 if(status != STATUS_OBJECT_NAME_COLLISION) 
    696                 { 
    697                         DbgPrint("CaptureFileMonitor: ERROR - FltCreateFile FAILED - %08x\n",status); 
    698                         return status; 
    699                 } 
    700         } 
    701         return STATUS_SUCCESS; 
    702 } 
    703  
    704 VOID 
    705 CreateADirectory(PFLT_INSTANCE pInstance, 
    706                                 PUNICODE_STRING pDirectoryPath) 
    707 { 
    708         NTSTATUS status; 
    709         OBJECT_ATTRIBUTES directoryAttributesObject; 
    710         IO_STATUS_BLOCK directoryIoStatusBlock; 
    711         LARGE_INTEGER allocate; 
    712         HANDLE hDirectory; 
    713         allocate.QuadPart = 0x1000; 
    714          
    715         InitializeObjectAttributes( 
    716                 &directoryAttributesObject, 
    717                 pDirectoryPath, 
    718                 OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, 
    719                 NULL, 
    720                 NULL 
    721                 ); 
    722  
    723         /* You can't use FltCreateFile here */ 
    724         /* Instance may not be the same instance we want to write to eg a 
    725            flash drive writing a file to a ntfs partition */ 
    726         status = ZwCreateFile( 
    727                 &hDirectory, 
    728                 0, 
    729                 &directoryAttributesObject, 
    730                 &directoryIoStatusBlock, 
    731                 &allocate, 
    732                 0, 
    733                 0, 
    734                 FILE_CREATE, 
    735                 FILE_DIRECTORY_FILE|FILE_SYNCHRONOUS_IO_NONALERT|FILE_WRITE_THROUGH, 
    736                 NULL, 
    737                 0 
    738                 ); 
    739         /* 
    740         status = FltCreateFile( 
    741                 fileManager.pFilter, 
    742                 pInstance, 
    743                 &hDirectory, 
    744                 0, 
    745                 &directoryAttributesObject, 
    746                 &directoryIoStatusBlock, 
    747                 &allocate, 
    748                 0, 
    749                 0, 
    750                 FILE_CREATE, 
    751                 FILE_DIRECTORY_FILE|FILE_SYNCHRONOUS_IO_NONALERT|FILE_WRITE_THROUGH, 
    752                 NULL, 
    753                 0, 
    754                 0 
    755                 ); 
    756         */ 
    757         if(NT_SUCCESS(status) && NT_SUCCESS(directoryIoStatusBlock.Status)) 
    758         { 
    759                 FltClose(hDirectory); 
    760         } else { 
    761                 if(status != STATUS_OBJECT_NAME_COLLISION) 
    762                 { 
    763                         DbgPrint("CaptureFileMonitor: CreateADirectory ERROR %08x & %08x\n", status, directoryIoStatusBlock.Status); 
    764                 } 
    765         } 
    766 } 
    767  
    768 VOID 
    769 GetDosDeviceName(PDEVICE_OBJECT pDeviceObject, 
    770                                  PUNICODE_STRING pShareName, 
    771                                  PUNICODE_STRING pDosName) 
    772 { 
    773         NTSTATUS status; 
    774         UNICODE_STRING tempDosDrive; 
    775  
    776         ObReferenceObject(pDeviceObject); 
    777  
    778         status = IoVolumeDeviceToDosName( 
    779                 (PVOID)pDeviceObject, 
    780                 &tempDosDrive); 
    781  
    782         pDosName->Length = 0; 
    783  
    784         if(NT_SUCCESS(status)) 
    785         { 
    786                 int i = 0; 
    787                 int wchars = tempDosDrive.Length/2; 
    788                 int pos = 0; 
    789                  
    790                 pDosName->MaximumLength = tempDosDrive.MaximumLength + 2; 
    791                 pDosName->Buffer = ExAllocatePoolWithTag(NonPagedPool, pDosName->MaximumLength, FILE_POOL_TAG); 
    792                  
    793                 if(pDosName->Buffer != NULL) 
    794                 { 
    795                         pDosName->Buffer[pos++] = '\\'; 
    796                         pDosName->Length += sizeof(WCHAR); 
    797                         for(i = 0; i < wchars; i++) 
    798                         { 
    799                                 if(tempDosDrive.Buffer[i] != 0x003A) 
    800                                 { 
    801                                         pDosName->Buffer[pos++] = tempDosDrive.Buffer[i]; 
    802                                         pDosName->Length += sizeof(WCHAR); // Unicode is 2-bytes 
    803                                 } 
    804                         } 
    805                         ExFreePool(tempDosDrive.Buffer); 
    806                 } 
    807         } else { 
    808                 if(pShareName != NULL) 
    809                 { 
    810                         pDosName->MaximumLength = pShareName->MaximumLength; 
    811                         pDosName->Buffer = ExAllocatePoolWithTag(NonPagedPool, pDosName->MaximumLength, FILE_POOL_TAG); 
    812                         if(pDosName->Buffer != NULL) 
    813                         { 
    814                                 RtlUnicodeStringCopy(pDosName, pShareName); 
    815                         } 
    816                 } else { 
    817                         pDosName->MaximumLength = 30; // Dont change this 
    818                         pDosName->Buffer = ExAllocatePoolWithTag(NonPagedPool, pDosName->MaximumLength, FILE_POOL_TAG); 
    819                         if(pDosName->Buffer != NULL) 
    820                         { 
    821                                 RtlUnicodeStringCatString(pDosName, L"\\UNKNOWN DRIVE"); 
    822                         } 
    823                 } 
    824         } 
    825         ObDereferenceObject(pDeviceObject); 
    826 } 
    827  
    828 VOID 
    829 CreateAllDirectories(PFLT_INSTANCE pInstance,  
    830                                 PUNICODE_STRING pRootDirectory,  
    831                                 PUNICODE_STRING pDirectory) 
    832 { 
    833         UNICODE_STRING totalDirectory; 
    834         UNICODE_STRING path; 
    835         USHORT dirSeperator = 0x005C; // Search for \ as a 16-bit unicode char 
    836         USHORT i = 0; 
    837         USHORT length = pDirectory->Length/2; 
    838         USHORT prevDirPosition = 0; 
    839  
    840         //RtlUnicodeStringInit(&path, L"\\??\\I:\\logs\\"); 
    841  
    842         totalDirectory.Length = 0; 
    843         totalDirectory.MaximumLength = pRootDirectory->MaximumLength + pDirectory->MaximumLength + 2; 
    844         totalDirectory.Buffer = ExAllocatePoolWithTag(NonPagedPool, totalDirectory.MaximumLength, FILE_POOL_TAG); 
    845          
    846         if(totalDirectory.Buffer == NULL) 
    847         { 
    848                 return; 
    849         } 
    850         //RtlAppendUnicodeString( 
    851         //RtlUnicodeStringCatString(&totalDirectory, L"\\??\\I:\\logs\\"); 
    852         RtlUnicodeStringCat(&totalDirectory,pRootDirectory); 
    853  
    854         for(i = 0; i < length; i++) 
    855         { 
    856                 USHORT tempChar = pDirectory->Buffer[i]; 
    857                 if(dirSeperator == tempChar) 
    858                 { 
    859                         if(i != 0) 
    860                         { 
    861                                 USHORT size = (i) - (prevDirPosition); 
    862                                  
    863                                 PWSTR dir = ExAllocatePoolWithTag(NonPagedPool, sizeof(WCHAR)*(size+1), FILE_POOL_TAG); 
    864  
    865                                 if(dir == NULL) 
    866                                 { 
    867                                         break; 
    868                                 } 
    869  
    870                                 RtlZeroMemory(dir, sizeof(WCHAR)*(size+1)); 
    871                                 RtlCopyMemory(dir,  pDirectory->Buffer+((prevDirPosition)), size*sizeof(WCHAR)); 
    872                                 dir[size] = '\0'; 
    873                                 RtlUnicodeStringCatString(&totalDirectory, dir); 
    874                                 //DbgPrint("Creating dir: %wZ\n", &totalDirectory); 
    875  
    876                                 CreateADirectory(pInstance, &totalDirectory); 
    877                                  
    878                                 //RtlUnicodeStringCatString(&totalDirectory, L"\\"); 
    879  
    880                                 ExFreePoolWithTag(dir, FILE_POOL_TAG); 
    881                                  
    882                                 prevDirPosition = i; 
    883                         }                
    884                 } 
    885         } 
    886         ExFreePoolWithTag(totalDirectory.Buffer, FILE_POOL_TAG); 
    887 } 
    888  
    889 VOID 
    890 CopyFileIfBeingDeleted( 
    891                                                 PFLT_CALLBACK_DATA Data, 
    892                                                 __in PCFLT_RELATED_OBJECTS FltObjects, 
    893                                                 PFLT_FILE_NAME_INFORMATION pFileNameInformation 
    894                                                 ) 
    895 { 
    896         NTSTATUS status; 
    897         BOOLEAN isDirectory; 
    898         FltIsDirectory(Data->Iopb->TargetFileObject,FltObjects->Instance,&isDirectory); 
    899         if(isDirectory) 
    900         { 
    901                 return; 
    902         } 
    903         if(Data->Iopb->MajorFunction == IRP_MJ_SET_INFORMATION) 
    904         { 
    905                 if(Data->Iopb->Parameters.SetFileInformation.FileInformationClass == FileDispositionInformation) 
    906                 { 
    907                         PFILE_DISPOSITION_INFORMATION pFileInfo = (PFILE_DISPOSITION_INFORMATION)Data->Iopb->Parameters.SetFileInformation.InfoBuffer; 
    908                          
    909                         /* If the file is marked for deletion back it up */ 
    910                         if(pFileInfo->DeleteFile && FltIsOperationSynchronous(Data)) 
    911                         { 
    912                                 //pFileEvent->majorFileEventType = 0x99; 
    913                                 status = FltParseFileNameInformation(pFileNameInformation); 
    914                                  
    915                                 if(NT_SUCCESS(status)) 
    916                                 { 
    917                                         if(fileManager.bCollectDeletedFiles) 
    918                                         { 
    919                                                 UNICODE_STRING completeFilePath; 
    920                                                 //UNICODE_STRING logDirectory; 
    921                                                 UNICODE_STRING fileDirectory; 
    922                                                 UNICODE_STRING fileDosDrive; 
    923  
    924                                                 //DbgPrint("On Delete: IoStatus - %08x\n", Data->IoStatus.Status); 
    925                                                 //DbgPrint("On Delete: FinalStatus - %08x\n", Data->Iopb->TargetFileObject->FinalStatus); 
    926  
    927                                                  
    928                                                 //RtlUnicodeStringInit(&logDirectory, L"\\??\\I:\\logs\\deleted_files"); 
    929  
    930                                                 /* Get the Dos drive name this file event was initiated on */ 
    931                                                 GetDosDeviceName(Data->Iopb->TargetFileObject->DeviceObject, &pFileNameInformation->Share, &fileDosDrive); 
    932                                                  
    933                                                 //DbgPrint("DosDrive: %wZ\n", &fileDosDrive); 
    934  
    935                                                 /* Allocate enough room to hold to whole path to the copied file */ 
    936                                                 /* <CAPTURE LOG DIRECTORY>\<DOS DRIVE>\<FILE DIRECTORY>\<FILE NAME> */ 
    937                                                 completeFilePath.Length = 0; 
    938                                                 completeFilePath.MaximumLength = fileManager.logDirectory.MaximumLength + fileDosDrive.MaximumLength + pFileNameInformation->FinalComponent.MaximumLength +  
    939                                                         pFileNameInformation->ParentDir.MaximumLength + 2; 
    940                                                 completeFilePath.Buffer = ExAllocatePoolWithTag(NonPagedPool, completeFilePath.MaximumLength, FILE_POOL_TAG); 
    941  
    942                                                 if(completeFilePath.Buffer != NULL) 
    943                                                 { 
    944                                                         /* Construct complete file path of where the copy of the deleted file is to be put */ 
    945                                                         RtlUnicodeStringCat(&completeFilePath, &fileManager.logDirectory); 
    946                                                         RtlUnicodeStringCat(&completeFilePath, &fileDosDrive); 
    947                                                         RtlUnicodeStringCat(&completeFilePath, &pFileNameInformation->ParentDir); 
    948                                                         RtlUnicodeStringCat(&completeFilePath, &pFileNameInformation->FinalComponent); 
    949                                                 } 
    950  
    951                                                 //DbgPrint("ParentDir: %wZ\n", &pFileNameInformation->ParentDir); 
    952                                                 //DbgPrint("FinalComponent: %wZ\n", &pFileNameInformation->FinalComponent); 
    953                                                 //DbgPrint("CompleteFilePath: %wZ\n", &completeFilePath); 
    954  
    955                                                 /* Allocate space for the file directory */ 
    956                                                 fileDirectory.Length = 0; 
    957                                                 fileDirectory.MaximumLength = pFileNameInformation->ParentDir.MaximumLength + fileDosDrive.MaximumLength + 2; 
    958                                                 fileDirectory.Buffer = ExAllocatePoolWithTag(NonPagedPool, fileDirectory.MaximumLength, FILE_POOL_TAG);                                  
    959                                                  
    960                                                 if(fileDirectory.Buffer != NULL) 
    961                                                 { 
    962                                                         /* Append the dos drive name, and then the directory */ 
    963                                                         RtlUnicodeStringCat(&fileDirectory, &fileDosDrive); 
    964                                                         RtlUnicodeStringCat(&fileDirectory, &pFileNameInformation->ParentDir); 
    965                                                  
    966                                                         //DbgPrint("FileDirectory: %wZ\n", &fileDirectory); 
    967                                                 } 
    968  
    969                                                 /* Create all the directories in the fileDirectory string */ 
    970                                                 CreateAllDirectories(FltObjects->Instance, &fileManager.logDirectory, &fileDirectory); 
    971                                                  
    972                                                 /* Path should exist now so copy the file */ 
    973                                                 CopyFile(Data, FltObjects, &completeFilePath); 
    974                                                  
    975                                                 /* Free all the UNICODE_STRING we allocated space for */ 
    976                                                 if(completeFilePath.Buffer != NULL) 
    977                                                         ExFreePoolWithTag(completeFilePath.Buffer, FILE_POOL_TAG); 
    978                                                 if(fileDirectory.Buffer != NULL) 
    979                                                         ExFreePoolWithTag(fileDirectory.Buffer, FILE_POOL_TAG); 
    980                                                 if(fileDosDrive.Buffer != NULL) 
    981                                                         ExFreePoolWithTag(fileDosDrive.Buffer, FILE_POOL_TAG); 
    982                                         } 
    983                                 } else { 
    984                                         DbgPrint("CaptureFileMonitor: ERROR - FltParseFileNameInformation - %08x\n", status); 
    985                                 } 
    986                         }        
    987                 } 
    988         } 
    989 } 
    990  
    991 FLT_PREOP_CALLBACK_STATUS 
    992 PreFileOperationCallback ( 
    993     __inout PFLT_CALLBACK_DATA Data, 
    994     __in PCFLT_RELATED_OBJECTS FltObjects, 
    995     __deref_out_opt PVOID *CompletionContext 
    996     ) 
    997 { 
    998         NTSTATUS status; 
    999         PFLT_FILE_NAME_INFORMATION pFileNameInformation; 
    1000         PFILE_EVENT pFileEvent; 
    1001         LARGE_INTEGER CurrentSystemTime; 
    1002         LARGE_INTEGER CurrentLocalTime; 
    1003         ULONG returnedLength; 
    1004         //HANDLE hThread; 
    1005         //HANDLE handle5; 
    1006         TIME_FIELDS TimeFields; 
    1007         BOOLEAN pathNameFound = FALSE; 
    1008         UNICODE_STRING filePath; 
    1009          
    1010         FLT_PREOP_CALLBACK_STATUS returnStatus = FLT_PREOP_SUCCESS_NO_CALLBACK; 
    1011          
    1012         /* If this is a callback for a FS Filter driver then we ignore the event */ 
    1013         if(FLT_IS_FS_FILTER_OPERATION(Data)) 
    1014         { 
    1015                 return FLT_PREOP_SUCCESS_NO_CALLBACK; 
    1016         } 
    1017  
    1018         /* Allocate a large 64kb string ... maximum path name allowed in windows */ 
    1019         filePath.Length = 0; 
    1020         filePath.MaximumLength = NTSTRSAFE_UNICODE_STRING_MAX_CCH * sizeof(WCHAR); 
    1021         filePath.Buffer = ExAllocatePoolWithTag(NonPagedPool, filePath.MaximumLength, FILE_POOL_TAG);  
    1022  
    1023         if(filePath.Buffer == NULL) 
    1024         { 
    1025                 return FLT_PREOP_SUCCESS_NO_CALLBACK; 
    1026         } 
    1027  
    1028         if (FltObjects->FileObject != NULL && Data != NULL) { 
    1029                 status = FltGetFileNameInformation( Data, 
    1030                                                                                         FLT_FILE_NAME_NORMALIZED | 
    1031                                                                                         FLT_FILE_NAME_QUERY_ALWAYS_ALLOW_CACHE_LOOKUP, 
    1032                                                                                         &pFileNameInformation ); 
    1033                 if(NT_SUCCESS(status)) 
    1034                 { 
    1035                         if(pFileNameInformation->Name.Length > 0) 
    1036                         { 
    1037                                 RtlUnicodeStringCopy(&filePath, &pFileNameInformation->Name); 
    1038                                 //RtlStringCbCopyUnicodeString(pFileEvent->filePath, 1024, &pFileNameInformation->Name); 
    1039                                 pathNameFound = TRUE; 
    1040                         } 
    1041                         /* Backup the file if it is marked for deletion */ 
    1042                         CopyFileIfBeingDeleted (Data,FltObjects,pFileNameInformation); 
    1043  
    1044                         /* Release the file name information structure if it was used */ 
    1045                         if(pFileNameInformation != NULL) 
    1046                         { 
    1047                                 FltReleaseFileNameInformation(pFileNameInformation); 
    1048                         } 
    1049                 } else { 
    1050                         NTSTATUS lstatus; 
    1051             PFLT_FILE_NAME_INFORMATION pLFileNameInformation; 
    1052             lstatus = FltGetFileNameInformation( Data, 
    1053                                 FLT_FILE_NAME_OPENED | FLT_FILE_NAME_QUERY_ALWAYS_ALLOW_CACHE_LOOKUP, 
    1054                                 &pLFileNameInformation); 
    1055                         if(NT_SUCCESS(lstatus)) 
    1056                         { 
    1057                                 if(pLFileNameInformation->Name.Length > 0) 
    1058                                 { 
    1059                                         RtlUnicodeStringCopy(&filePath, &pLFileNameInformation->Name); 
    1060                                         //RtlStringCbCopyUnicodeString(pFileEvent->filePath, 1024, &pLFileNameInformation->Name); 
    1061                                         pathNameFound = TRUE; 
    1062                                 } 
    1063                                 /* Backup the file if it is marked for deletion */ 
    1064                                 CopyFileIfBeingDeleted (Data,FltObjects,pFileNameInformation); 
    1065  
    1066                                 /* Release the file name information structure if it was used */ 
    1067                                 if(pLFileNameInformation != NULL) 
    1068                                 { 
    1069                                         FltReleaseFileNameInformation(pLFileNameInformation); 
    1070                                 } 
    1071                         } 
    1072                 } 
    1073         } 
    1074  
    1075         /* If path name could not be found the file monitor uses the file name stored 
    1076            in the FileObject. The documentation says that we shouldn't use this info 
    1077            as it may not be correct. It does however allow us get some nice file events 
    1078            such as the system process writing to the $MFT file etc. Remove this code if 
    1079            problems start to occur */ 
    1080         if( (pathNameFound == FALSE) &&  
    1081                 (FltObjects->FileObject != NULL) && 
    1082                 (FltObjects->FileObject->RelatedFileObject == NULL) && 
    1083                 (FltObjects->FileObject->FileName.Length > 0)) 
    1084         { 
    1085                 NTSTATUS status; 
    1086                 ULONG size; 
    1087                 UNICODE_STRING szTempPath; 
    1088                 UNICODE_STRING szDevice; 
    1089                 UNICODE_STRING szFileNameDevice; 
    1090  
    1091                 /* Check the FileObject->FileName isn't already a complete filepath */ 
    1092                 szFileNameDevice.Length = FltObjects->FileObject->FileName.Length; 
    1093                 szFileNameDevice.MaximumLength = FltObjects->FileObject->FileName.MaximumLength; 
    1094                 szFileNameDevice.Buffer = ExAllocatePoolWithTag(NonPagedPool, szFileNameDevice.MaximumLength, FILE_POOL_TAG); 
    1095                 RtlInitUnicodeString(&szDevice, L"\\Device"); 
    1096                 if(FltObjects->FileObject->FileName.Length >= szDevice.Length) 
    1097                 { 
    1098                         RtlUnicodeStringCchCopyN(&szFileNameDevice, &FltObjects->FileObject->FileName, 7); 
    1099                 } 
    1100  
    1101                 if(RtlEqualUnicodeString(&szDevice, &szFileNameDevice, TRUE)) 
    1102                 { 
    1103                         RtlUnicodeStringCopy(&filePath, &FltObjects->FileObject->FileName); 
    1104                         pathNameFound = TRUE; 
    1105                 } else { 
    1106                         szTempPath.Length = 0; 
    1107                         szTempPath.MaximumLength = FltObjects->FileObject->FileName.MaximumLength + 2; 
    1108  
    1109                         /* Get the volume name of where the event came from */ 
    1110                         status = FltGetVolumeName( 
    1111                                                 FltObjects->Volume, 
    1112                                                 NULL, 
    1113                                                 &size 
    1114                                                 ); 
    1115                         if(status == STATUS_BUFFER_TOO_SMALL) 
    1116                         { 
    1117                                 szTempPath.MaximumLength += (USHORT)size; 
    1118                                 szTempPath.Buffer = ExAllocatePoolWithTag(NonPagedPool, szTempPath.MaximumLength, FILE_POOL_TAG); 
    1119                                  
    1120                                 if(szTempPath.Buffer != NULL) 
    1121                                 { 
    1122                                         status = FltGetVolumeName( 
    1123                                                         FltObjects->Volume, 
    1124                                                         &szTempPath, 
    1125                                                         &size 
    1126                                                         ); 
    1127                                         if(NT_SUCCESS(status)) 
    1128                                         { 
    1129                                                 /* Append the file event to the volume name */ 
    1130                                                 RtlUnicodeStringCat(&szTempPath, &FltObjects->FileObject->FileName); 
    1131                                                 RtlUnicodeStringCopy(&filePath, &szTempPath); 
    1132                                                 pathNameFound = TRUE; 
    1133                                         } 
    1134                                         ExFreePoolWithTag(szTempPath.Buffer, FILE_POOL_TAG); 
    1135                                 } 
    1136                         } 
    1137                 } 
    1138                 ExFreePoolWithTag(szFileNameDevice.Buffer, FILE_POOL_TAG); 
    1139         } 
    1140  
    1141         if(!pathNameFound) 
    1142         { 
    1143                 RtlUnicodeStringCatString(&filePath, L"UNKNOWN");  
    1144         } 
    1145  
    1146         /* Allocate file event and put the values into it */ 
    1147         /* NOTE this is freed in the post op callback (which should always get called) */ 
    1148         pFileEvent = ExAllocatePoolWithTag(NonPagedPool, sizeof(FILE_EVENT)+filePath.Length+sizeof(WCHAR), FILE_POOL_TAG); 
    1149          
    1150         if(pFileEvent == NULL) 
    1151         { 
    1152                 ExFreePoolWithTag(filePath.Buffer, FILE_POOL_TAG); 
    1153                 return FLT_PREOP_SUCCESS_NO_CALLBACK; 
    1154         } 
    1155  
    1156         /* Copy file path into file event */ 
    1157         pFileEvent->filePathLength = filePath.Length+sizeof(WCHAR); 
    1158         RtlStringCbCopyUnicodeString(pFileEvent->filePath, pFileEvent->filePathLength, &filePath); 
    1159         /* Free the allocated storage for a filepath */ 
    1160         ExFreePoolWithTag(filePath.Buffer, FILE_POOL_TAG); 
    1161  
    1162         pFileEvent->majorFileEventType = Data->Iopb->MajorFunction; 
    1163         pFileEvent->minorFileEventType = Data->Iopb->MinorFunction; 
    1164         pFileEvent->processId = 0; 
    1165  
    1166         if (FltObjects->FileObject != NULL) 
    1167         { 
    1168                 pFileEvent->flags = FltObjects->FileObject->Flags; 
    1169         } 
    1170  
    1171         if(Data->Iopb->MajorFunction == IRP_MJ_SET_INFORMATION) 
    1172         { 
    1173                 if(Data->Iopb->Parameters.SetFileInformation.FileInformationClass == FileDispositionInformation) 
    1174                 { 
    1175                         PFILE_DISPOSITION_INFORMATION pFileInfo = (PFILE_DISPOSITION_INFORMATION)Data->Iopb->Parameters.SetFileInformation.InfoBuffer; 
    1176                         /* If the file is marked for deletion back it up */ 
    1177                         if(pFileInfo->DeleteFile) 
    1178                         { 
    1179                                 pFileEvent->majorFileEventType = 0x99; 
    1180                         } 
    1181                 } 
    1182         } 
    1183  
    1184         /* Get the process id of the file event */ 
    1185         /* NOTE we are kinda using an undocumented function here but its all available 
    1186            on the interweb. Plus its much better than accessing the PETHREAD structure 
    1187            which could change at any time. Also, this one is available to userspace 
    1188            programs so it should be safe to use. We have to use this function because 
    1189            a file I/O may either be processed in the context of the userspace program 
    1190            or the system context. This uses the thread data from FLT_CALLBACK_DATA to 
    1191            determine which process it actually came from. We default back to getting 
    1192            the current process id if all else fails. */ 
    1193         /* SECOND NOTE FltGetRequestorProcessId does not get the correct process id, it 
    1194            looks like it still get the proces id of the context the pre callback gets 
    1195            called in */ 
    1196         /* 
    1197         status = ObOpenObjectByPointer(Data->Thread,  
    1198                 OBJ_KERNEL_HANDLE,  
    1199                 NULL,  
    1200                 0,  
    1201                 0,  
    1202                 KernelMode,  
    1203                 &hThread); 
    1204         if(NT_SUCCESS(status)) 
    1205         { 
    1206                 THREAD_BASIC_INFORMATION threadBasicInformation; 
    1207  
    1208                 status = ZwQueryInformationThread(hThread,  
    1209                         ThreadBasicInformation,  
    1210                         &threadBasicInformation,  
    1211                         sizeof(THREAD_BASIC_INFORMATION),  
    1212                         &returnedLength ); 
    1213                 if(NT_SUCCESS(status)) 
    1214                 { 
    1215                         pFileEvent->processId = (HANDLE)threadBasicInformation.UniqueProcessId; 
    1216                         handle5 = pFileEvent->processId; 
    1217                         //DbgPrint("Process4: %i\n", pFileEvent->processId); 
    1218                 } else {                 
    1219                         DbgPrint("ZwQueryInformationThread FAILED: %08x\n", status); 
    1220                 } 
    1221                 ZwClose(hThread); 
    1222         } else {                 
    1223                 DbgPrint("ObOpenObjectByPointer FAILED: %08x\n", status); 
    1224         } 
    1225         */ 
    1226  
    1227         /* New safe get correct process id. One above causes blue screen in some cases */ 
    1228         if(Data->Thread != NULL) 
    1229         { 
    1230                 PEPROCESS pProcess = IoThreadToProcess( Data->Thread ); 
    1231                 pFileEvent->processId = PsGetProcessId(pProcess); 
    1232         } else { 
    1233                 pFileEvent->processId = PsGetCurrentProcessId(); 
    1234                 DbgPrint("CaptureFileMonitor: Process id may be incorrect\n"); 
    1235         } 
    1236 /* 
    1237         DbgPrint("%i [%i %i] %s %i %i (%i, %i, %i) %i %i %i %i %i : %ls\n",  
    1238                         KeGetCurrentIrql(), 
    1239                         PsIsSystemThread(Data->Thread), 
    1240                         PsIsSystemThread(PsGetCurrentThread()), 
    1241                         FltGetIrpName(Data->Iopb->MajorFunction), 
    1242                         Data->Iopb->MajorFunction, 
    1243                         Data->Iopb->MinorFunction, 
    1244                         pFileEvent->processId, 
    1245                         PsGetCurrentProcessId(), 
    1246                         FltGetRequestorProcessId(Data), 
    1247                         FLT_IS_FASTIO_OPERATION(Data), 
    1248                         FLT_IS_FS_FILTER_OPERATION(Data), 
    1249                         FLT_IS_IRP_OPERATION(Data), 
    1250                         FLT_IS_REISSUED_IO(Data), 
    1251                         FLT_IS_SYSTEM_BUFFER(Data), 
    1252                         pFileEvent->filePath); 
    1253 */                       
    1254         //ASSERT(pFileEvent->processId != 0); 
    1255  
    1256         /* Get the time this event occured */ 
    1257         KeQuerySystemTime(&CurrentSystemTime); 
    1258         ExSystemTimeToLocalTime(&CurrentSystemTime,&CurrentLocalTime); 
    1259         RtlTimeToTimeFields(&CurrentLocalTime,&TimeFields); 
    1260         pFileEvent->time = TimeFields; 
    1261  
    1262  
    1263  
    1264         /* Pass the created file event to the post operation of this pre file operation */ 
    1265         if (Data->Iopb->MajorFunction == IRP_MJ_SHUTDOWN) 
    1266         { 
    1267                 PostFileOperationCallback( Data, 
    1268                                                 FltObjects, 
    1269                                                 pFileEvent, 
    1270                                                 0 ); 
    1271                 return FLT_PREOP_SUCCESS_NO_CALLBACK; 
    1272         } else { 
    1273                 *CompletionContext = pFileEvent; 
    1274                 return FLT_PREOP_SUCCESS_WITH_CALLBACK; 
    1275         } 
    1276  
    1277      
    1278 } 
    1279  
    1280 VOID DeferredCopyFunction(IN PFLT_DEFERRED_IO_WORKITEM WorkItem,  
    1281                                                   IN PFLT_CALLBACK_DATA Data,  
    1282                                                   IN PVOID CompletionContext) 
    1283 { 
    1284  
    1285         FltCompletePendedPreOperation(Data,FLT_PREOP_SUCCESS_NO_CALLBACK,CompletionContext);  
    1286         FltFreeDeferredIoWorkItem(WorkItem); 
    1287         busy = FALSE; 
    1288 } 
    1289  
    1290 FLT_POSTOP_CALLBACK_STATUS PostFileOperationCallback ( IN OUT PFLT_CALLBACK_DATA Data,  
    1291         IN PCFLT_RELATED_OBJECTS FltObjects,  
    1292         IN PVOID CompletionContext,  
    1293         IN FLT_POST_OPERATION_FLAGS Flags) 
    1294 { 
    1295         /* You cannot properly get the full path name of a file operation in the postop 
    1296            this is documented in the WDK documentation regarding this function. READ IT ... 
    1297            in partcular the Comments section regarding the IRP level that this can run in */ 
    1298         PFILE_EVENT pFileEvent; 
    1299  
    1300         pFileEvent = (PFILE_EVENT)CompletionContext; 
    1301  
    1302         if(pFileEvent == NULL) 
    1303         { 
    1304                 return FLT_POSTOP_FINISHED_PROCESSING; 
    1305         } 
    1306  
    1307         /* If the post file operation is draining then don't worry about adding the event */ 
    1308         if(FlagOn(Flags, FLTFL_POST_OPERATION_DRAINING)) 
    1309         { 
    1310                 if(pFileEvent != NULL) 
    1311                 { 
    1312                         ExFreePoolWithTag(pFileEvent, FILE_POOL_TAG); 
    1313                         pFileEvent = NULL; 
    1314                 } 
    1315                 return FLT_POSTOP_FINISHED_PROCESSING; 
    1316         } 
    1317  
    1318         pFileEvent->status = Data->IoStatus.Status; 
    1319         pFileEvent->information = Data->IoStatus.Information; 
    1320  
    1321         if(!QueueFileEvent(pFileEvent)) 
    1322         { 
    1323                 if(pFileEvent != NULL) 
    1324                 { 
    1325                         ExFreePoolWithTag(pFileEvent, FILE_POOL_TAG); 
    1326                         pFileEvent = NULL; 
    1327                 } 
    1328         } 
    1329     return FLT_POSTOP_FINISHED_PROCESSING; 
    1330 } 
    1331  
    1332 VOID UpdateLastContactTime() 
    1333 { 
    1334         fileManager.lastContactTime = GetCurrentTime(); 
    1335 } 
    1336  
    1337 ULONG GetCurrentTime() 
    1338 { 
    1339         LARGE_INTEGER currentSystemTime; 
    1340         LARGE_INTEGER currentLocalTime; 
    1341         ULONG time; 
    1342  
    1343         KeQuerySystemTime(&currentSystemTime); 
    1344         ExSystemTimeToLocalTime(&currentSystemTime,&currentLocalTime); 
    1345         RtlTimeToSecondsSince1970(&currentLocalTime, &time); 
    1346         return time; 
    1347 } 
    1348  
    1349 BOOLEAN QueueFileEvent(PFILE_EVENT pFileEvent) 
    1350 { 
    1351         BOOLEAN inserted = FALSE; 
    1352         if(     (GetCurrentTime()-fileManager.lastContactTime) <= USERSPACE_CONNECTION_TIMEOUT) 
    1353         { 
    1354                 PFILE_EVENT_PACKET pFileEventPacket; 
    1355                  
    1356                 pFileEventPacket = ExAllocatePoolWithTag(NonPagedPool, sizeof(FILE_EVENT_PACKET), FILE_POOL_TAG); 
    1357                 if(pFileEventPacket != NULL) 
    1358                 { 
    1359                         //RtlCopyMemory(&pFileEventPacket->fileEvent, pFileEvent, sizeof(FILE_EVENT)); 
    1360                         pFileEventPacket->pFileEvent = pFileEvent; 
    1361                         ExInterlockedInsertTailList(&fileManager.lQueuedFileEvents, &pFileEventPacket->Link, &fileManager.lQueuedFileEventsSpinLock); 
    1362                         inserted = TRUE; 
    1363                 } 
    1364         } 
    1365         return inserted; 
    1366 } 
    1367  
    1368 NTSTATUS FilterUnload ( IN FLT_FILTER_UNLOAD_FLAGS Flags ) 
    1369 { 
    1370         PLIST_ENTRY pListHead; 
    1371         PFILE_EVENT_PACKET pFileEventPacket; 
    1372         FltCloseCommunicationPort( fileManager.pServerPort ); 
    1373  
    1374         if(fileManager.bReady == TRUE) 
    1375         { 
    1376                 FltUnregisterFilter( fileManager.pFilter );      
    1377                 KeCancelTimer(&fileManager.connectionCheckerTimer); 
    1378         } 
    1379  
    1380         // Free the log directory 
    1381         if(fileManager.logDirectory.Buffer != NULL) 
    1382         { 
    1383                 ExFreePoolWithTag(fileManager.logDirectory.Buffer, FILE_POOL_TAG); 
    1384                 fileManager.logDirectory.Buffer = NULL; 
    1385         } 
    1386         fileManager.bCollectDeletedFiles = FALSE; 
    1387  
    1388         // Free the linked list containing all the left over file events 
    1389         FreeQueuedEvents(); 
    1390  
    1391         return STATUS_SUCCESS; 
    1392 } 
    1393  
    1394 NTSTATUS SetupCallback (IN PCFLT_RELATED_OBJECTS  FltObjects, 
    1395         IN FLT_INSTANCE_SETUP_FLAGS  Flags, 
    1396         IN DEVICE_TYPE  VolumeDeviceType, 
    1397         IN FLT_FILESYSTEM_TYPE  VolumeFilesystemType) 
    1398 { 
    1399         // Always return true so that we attach to all known volumes and all future volumes (USB flashdrives etc) 
    1400         if (VolumeDeviceType == FILE_DEVICE_NETWORK_FILE_SYSTEM) { 
     142        ULONG volume_name_length; 
     143        UNICODE_STRING volume_name; 
     144 
     145        // Don't attach to network file systems ... for now 
     146        if(volume_device_type == FILE_DEVICE_NETWORK_FILE_SYSTEM) 
     147        { 
    1401148       return STATUS_FLT_DO_NOT_ATTACH; 
    1402149    } 
    1403150 
     151        // Print out the volume name we are attaching to 
     152        status = FltGetVolumeName(filter_objects->Volume, NULL, &volume_name_length); 
     153        if(NT_SUCCESS(status)) 
     154        { 
     155                volume_name.Length = 0; 
     156                volume_name.MaximumLength = volume_name_length; 
     157                volume_name.Buffer = (wchar_t*)ExAllocatePoolWithTag(NonPagedPool, volume_name_length, FILE_POOL_TAG); 
     158                 
     159                if(volume_name.Buffer) 
     160                { 
     161                        status = FltGetVolumeName(filter_objects->Volume, &volume_name, &volume_name_length); 
     162                        if(NT_SUCCESS(status)) 
     163                        { 
     164                                DbgPrint("CaptureFileMonitor: Attached to volume - %wZ\n", &volume_name); 
     165                        } 
     166                        ExFreePoolWithTag(volume_name.Buffer, FILE_POOL_TAG); 
     167                } 
     168        } 
     169 
    1404170    return STATUS_SUCCESS; 
    1405171} 
    1406172 
    1407 NTSTATUS MessageCallback ( 
    1408     __in PVOID ConnectionCookie, 
    1409     __in_bcount_opt(InputBufferSize) PVOID InputBuffer, 
    1410     __in ULONG InputBufferSize, 
    1411     __out_bcount_part_opt(OutputBufferSize,*ReturnOutputBufferLength) PVOID OutputBuffer, 
    1412     __in ULONG OutputBufferSize, 
    1413     __out PULONG ReturnOutputBufferLength 
    1414     ) 
    1415 {        
     173NTSTATUS FilterUnload( FLT_FILTER_UNLOAD_FLAGS flag ) 
     174{ 
     175        FltCloseCommunicationPort(file_manager.server_port); 
     176 
     177        FltUnregisterFilter(file_manager.filter);        
     178 
     179        return STATUS_SUCCESS; 
     180} 
     181 
     182FLT_PREOP_CALLBACK_STATUS FilePreOperationCallback( 
     183        IN OUT PFLT_CALLBACK_DATA data, 
     184        IN PCFLT_RELATED_OBJECTS filter_objects, 
     185        OUT PVOID *completion_context) 
     186{ 
    1416187        NTSTATUS status; 
    1417         FILEMONITOR_COMMAND command; 
    1418         PLIST_ENTRY pListHead; 
    1419         PFILE_EVENT_PACKET pFileEventPacket; 
    1420         UINT bufferSpace = OutputBufferSize; 
    1421         UINT bufferSpaceUsed = 0; 
    1422         PCHAR pOutputBuffer = OutputBuffer; 
    1423  
    1424         if ((InputBuffer != NULL) && 
    1425                 (InputBufferSize >= (FIELD_OFFSET(FILEMONITOR_MESSAGE,Command) + 
    1426                              sizeof(FILEMONITOR_COMMAND)))) 
    1427         { 
    1428         try  { 
    1429             command = ((PFILEMONITOR_MESSAGE) InputBuffer)->Command; 
    1430         } except( EXCEPTION_EXECUTE_HANDLER ) { 
    1431             return GetExceptionCode(); 
    1432         } 
     188        HANDLE process_id; 
     189        EventId event_id = -1; 
     190        BOOLEAN file_name_found = FALSE; 
     191        BOOLEAN normalised_name = FALSE; 
     192        EventRingList* event_ring_list = NULL; 
     193        PFLT_FILE_NAME_INFORMATION file_name_information; 
     194 
     195        event_ring_list = &file_manager.event_ring_list; 
     196 
     197        DbgBreakPoint(); 
     198 
     199 
     200        if(!filter_objects->FileObject || !data) 
     201        { 
     202                return FLT_PREOP_SUCCESS_NO_CALLBACK; 
     203        } 
     204 
     205        event_id = CreateEvent( event_ring_list ); 
     206 
     207        if(data->Thread) 
     208        { 
     209                PEPROCESS process = IoThreadToProcess(data->Thread); 
     210                process_id = PsGetProcessId(process); 
     211        } else { 
     212                process_id = PsGetCurrentProcessId(); 
     213                DbgPrint("CaptureFileMonitor: WARNING - process id may be incorrect\n"); 
     214        } 
     215 
     216        AddEventData(event_ring_list, event_id, process_id_hash, int_t, &process_id, sizeof( ULONG ) ); 
     217 
     218        // Get the path of file 
     219        // Try getting the normalized file name from the filter manager cache 
     220        status = FltGetFileNameInformation( 
     221                data, 
     222                FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_ALWAYS_ALLOW_CACHE_LOOKUP, 
     223                &file_name_information); 
     224 
     225        // Try getting the original opened file name from the filter manager cache if 
     226        // the above didn't succeed 
     227        if(!NT_SUCCESS(status)) 
     228        { 
     229                status = FltGetFileNameInformation( 
     230                        data, 
     231                        FLT_FILE_NAME_OPENED | FLT_FILE_NAME_QUERY_ALWAYS_ALLOW_CACHE_LOOKUP, 
     232                        &file_name_information); 
     233        } 
     234        else 
     235        { 
     236                normalised_name = TRUE; 
     237        } 
     238 
     239        if(NT_SUCCESS(status)) 
     240        { 
     241                // Copy the file name into the file event 
     242                AddEventData(event_ring_list, event_id,  
     243                        file_name_hash, pwchar_t,  
     244                        file_name_information->Name.Buffer, file_name_information->Name.Length); 
    1433245                 
    1434                 switch(command) { 
    1435                         case GetFileEvents: 
    1436                                 UpdateLastContactTime(); 
    1437                                 while(!IsListEmpty(&fileManager.lQueuedFileEvents) &&  
    1438                                         (bufferSpaceUsed < bufferSpace) && 
    1439                                         ((bufferSpace-bufferSpaceUsed) >= sizeof(FILE_EVENT))) 
    1440                                 { 
    1441                                         UINT fileEventSize = 0; 
    1442  
    1443                                         pListHead = ExInterlockedRemoveHeadList(&fileManager.lQueuedFileEvents, &fileManager.lQueuedFileEventsSpinLock); 
    1444                                         pFileEventPacket = CONTAINING_RECORD(pListHead, FILE_EVENT_PACKET, Link); 
    1445                                          
    1446                                         // Get the file event size, taking into account the variable path name size 
    1447                                         fileEventSize = sizeof(FILE_EVENT)+pFileEventPacket->pFileEvent->filePathLength; 
    1448                                         if((bufferSpace-bufferSpaceUsed) >= fileEventSize) 
    1449                                         { 
    1450                                                 // Copy the memory into the user space buffer 
    1451                                                 RtlCopyMemory(pOutputBuffer+bufferSpaceUsed, pFileEventPacket->pFileEvent, fileEventSize); 
    1452                                                 bufferSpaceUsed += fileEventSize; 
    1453                                                  
    1454                                                 // Free the allocated packet and file event 
    1455                                                 ExFreePoolWithTag(pFileEventPacket->pFileEvent, FILE_POOL_TAG); 
    1456                                                 ExFreePoolWithTag(pFileEventPacket, FILE_POOL_TAG); 
    1457                                         } else { 
    1458                                                 // Not enough user space buffer left so put the packet we just got from the list back 
    1459                                                 ExInterlockedInsertHeadList(&fileManager.lQueuedFileEvents, &pFileEventPacket->Link, &fileManager.lQueuedFileEventsSpinLock); 
    1460                                                 break; 
    1461                                         } 
    1462                                 } 
    1463                                  
    1464                                 *ReturnOutputBufferLength = bufferSpaceUsed; 
    1465                                 status = STATUS_SUCCESS; 
    1466                                 break; 
    1467                         case SetupMonitor: 
    1468                                 if(bufferSpace == sizeof(FILEMONITOR_SETUP)) 
    1469                                 { 
    1470                                         PFILEMONITOR_SETUP pFileMonitorSetup = (PFILEMONITOR_SETUP)pOutputBuffer;                        
    1471                                         if(pFileMonitorSetup->bCollectDeletedFiles) 
    1472                                         { 
    1473                                                 USHORT logDirectorySize; 
    1474                                                 UNICODE_STRING uszTempString; 
    1475                                                  
    1476                                                 // Create a temp path name that contains the fudge stuff to open files in kernel space 
    1477                                                 RtlInitUnicodeString(&uszTempString, L"\\??\\"); 
    1478                                                 logDirectorySize = uszTempString.MaximumLength + pFileMonitorSetup->nLogDirectorySize + 2; 
    1479                                                  
    1480                                                 // If the log director is already defined free it 
    1481                                                 if(fileManager.logDirectory.Buffer != NULL) 
    1482                                                 { 
    1483                                                         ExFreePoolWithTag(fileManager.logDirectory.Buffer, FILE_POOL_TAG); 
    1484                                                         fileManager.logDirectory.Buffer = NULL; 
    1485                                                 } 
    1486  
    1487                                                 fileManager.logDirectory.Buffer = ExAllocatePoolWithTag(NonPagedPool, logDirectorySize+sizeof(UNICODE_STRING)+2, FILE_POOL_TAG); 
    1488                                                  
    1489                                                 if(fileManager.logDirectory.Buffer != NULL) 
    1490                                                 { 
    1491                                                         fileManager.logDirectory.Length = 0; 
    1492                                                         fileManager.logDirectory.MaximumLength = logDirectorySize;                                                                               
    1493                                                         fileManager.bCollectDeletedFiles = pFileMonitorSetup->bCollectDeletedFiles; 
    1494  
    1495                                                         // Copy delete log directory into the file manager 
    1496                                                         RtlUnicodeStringCat(&fileManager.logDirectory, &uszTempString); 
    1497                                                         RtlUnicodeStringCatString(&fileManager.logDirectory, pFileMonitorSetup->wszLogDirectory); 
    1498                                                  
    1499                                                         DbgPrint("CaptureFileMonitor: Collecting deleted files: %wZ\n", &fileManager.logDirectory); 
    1500                                                 } 
    1501                                         } else { 
    1502                                                 fileManager.bCollectDeletedFiles = FALSE; 
    1503                                                 // If we were previously collecting deleted files we must have had a log directory 
    1504                                                 // set ... so free it if we did 
    1505                                                 if(fileManager.logDirectory.Buffer != NULL) 
    1506                                                 { 
    1507                                                         ExFreePoolWithTag(fileManager.logDirectory.Buffer, FILE_POOL_TAG); 
    1508                                                         fileManager.logDirectory.Buffer = NULL; 
    1509                                                 }                
    1510                                         } 
    1511                                 } 
    1512                                 status = STATUS_SUCCESS; 
    1513                         default: 
    1514                                 status = STATUS_INVALID_PARAMETER; 
    1515                                 break; 
    1516  
    1517                 } 
    1518         } else { 
    1519                 status = STATUS_INVALID_PARAMETER; 
    1520         } 
    1521         return status; 
    1522 } 
    1523  
    1524 NTSTATUS ConnectCallback( 
    1525     __in PFLT_PORT ClientPort, 
    1526     __in PVOID ServerPortCookie, 
    1527     __in_bcount(SizeOfContext) PVOID ConnectionContext, 
    1528     __in ULONG SizeOfContext, 
    1529     __deref_out_opt PVOID *ConnectionCookie 
    1530     ) 
    1531 { 
    1532         ASSERT( fileManager.pClientPort == NULL ); 
    1533     fileManager.pClientPort = ClientPort; 
    1534     return STATUS_SUCCESS; 
    1535 } 
    1536  
    1537 VOID DisconnectCallback(__in_opt PVOID ConnectionCookie) 
    1538 { 
    1539         PLIST_ENTRY pListHead; 
    1540         PFILE_EVENT_PACKET pFileEventPacket; 
     246                file_name_found = TRUE; 
     247                 
     248                FltReleaseFileNameInformation(file_name_information); 
     249        } 
     250 
     251        // Try one last time to get the file name 
     252        // Check that the fileobject doesn't already contain the complete filepath 
     253        // if it doesn't construct one from the partial path stored in the fileobject 
     254        if(!file_name_found) 
     255        { 
     256                //if(StringBeginsWith(&filter_objects->FileObject->FileName, L"\\Device")) 
     257                //{ 
     258                //      // Copy the file object name into the file event 
     259                //      AddEventData(event_ring_list, event_id,  
     260                //              file_name_hash, pwchar_t,  
     261                //              filter_objects->FileObject->FileName.Buffer, filter_objects->FileObject->FileName.Length); 
     262                //} 
     263                //else 
     264                //{ 
     265                //      ULONG volume_name_length = 0; 
     266 
     267                //      status = FltGetVolumeName(filter_objects->Volume, NULL, &volume_name_length); 
     268                //      if(NT_SUCCESS(status)) 
     269                //      { 
     270                //              UNICODE_STRING volume_name; 
     271 
     272                //              volume_name.Length = 0; 
     273                //              volume_name.MaximumLength = volume_name_length; 
     274                //              volume_name.Buffer = (wchar_t*)ReserveEventDataSpace(event_ring_list, event_id, file_name_hash, pwchar_t, volume_name_length); 
     275                //               
     276                //              if(volume_name.Buffer) 
     277                //              { 
     278                //                      status = FltGetVolumeName(filter_objects->Volume, &volume_name, &volume_name_length); 
     279                //              } 
     280                //      } 
     281                //} 
     282        } 
    1541283         
    1542         // Free the linked list containing all the left over file events 
    1543         FreeQueuedEvents(); 
    1544  
    1545         // Free the log directory if one was allocated 
    1546         if(fileManager.logDirectory.Buffer != NULL) 
    1547         { 
    1548                 ExFreePoolWithTag(fileManager.logDirectory.Buffer, FILE_POOL_TAG); 
    1549                 fileManager.logDirectory.Buffer = NULL; 
    1550         } 
    1551         fileManager.bCollectDeletedFiles = FALSE; 
    1552  
    1553         FltCloseClientPort( fileManager.pFilter, &fileManager.pClientPort ); 
    1554 } 
     284        if(normalised_name &&  
     285                (IS_CREATE_OPERATION(data) ||  
     286                 IS_RENAME_OPERATION(data) ||  
     287                 IS_HARDLINK_OPERATION(data))) 
     288        { 
     289                // We have to get the tunnelled name ... sigh! 
     290 
     291        } 
     292 
     293        return FLT_PREOP_SUCCESS_WITH_CALLBACK; 
     294} 
     295 
     296FLT_POSTOP_CALLBACK_STATUS FilePostOperationCallback( 
     297        IN OUT PFLT_CALLBACK_DATA data, 
     298        IN PCFLT_RELATED_OBJECTS filter_objects, 
     299        IN PVOID completion_context, 
     300        IN FLT_POST_OPERATION_FLAGS flags) 
     301{ 
     302        if(FlagOn(flags, FLTFL_POST_OPERATION_DRAINING)) 
     303        { 
     304                // TODO Do we need to actual create the event or not? 
     305                // Previously we didn't 
     306        } 
     307 
     308        return FLT_POSTOP_FINISHED_PROCESSING; 
     309} 
  • capture-hpc/branches/dev/capture-client/KernelDrivers/CaptureKernelDrivers/FileMonitor/Sources

    r98 r361  
    55 
    66TARGETLIBS=$(TARGETLIBS) \ 
    7            $(IFSKIT_LIB_PATH)\fltMgr.lib 
     7           $(IFSKIT_LIB_PATH)\fltMgr.lib        \ 
     8           ..\Common\i386\EventRingList.lib     \ 
     9 
     10INCLUDES=..\Common 
    811 
    912SOURCES=CaptureFileMonitor.c   \ 
  • capture-hpc/branches/dev/capture-client/KernelDrivers/CaptureKernelDrivers/dirs

    r360 r361  
    1 DIRS=Common RegistryMonitor FileMonitor ProcessMonitor 
     1DIRS=Common RegistryMonitor FileMonitor ProcessMonitor NetworkMonitor 
  • capture-hpc/branches/dev/capture-client/OptionsManager.cpp

    r352 r361  
    3030 
    3131void 
    32 OptionsManager::onOptionEvent(const std::wstring& event_type, const Event& event) 
     32OptionsManager::onOptionEvent(const std::wstring& eventType, const Element& e) 
    3333{ 
    34         if(event_type == L"option") 
    35         {        
    36                 std::wstring name = L""; 
    37                 Variant* value = NULL; 
    38                 stdext::hash_map<std::wstring, Variant*>::const_iterator it; 
    39                 for(it = event.getAttributes().begin(); it != event.getAttributes().end(); it++) 
    40                 { 
    41                         if(it->first == L"name") { 
    42                                 name = it->first; 
    43                         } else if(it->first == L"value") { 
    44                                 value = it->second; 
    45                         } 
    46                 } 
    47                 if(name != L"" && value) 
    48                 { 
    49                         setOption(name, *value); 
    50                 } 
     34        if(eventType != L"option") 
     35        { 
     36                LOG(WARN, "OptionManager: Received unhandled event - %ls", eventType); 
     37                return; 
    5138        } 
     39 
     40        setOption(e.GetAttribute(L"name"), e.GetAttribute(L"value")); 
    5241} 
    5342 
  • capture-hpc/branches/dev/capture-client/OptionsManager.h

    r352 r361  
    6565 
    6666private: 
    67         void onOptionEvent(const std::wstring& event_type, const Event& event); 
     67        void onOptionEvent(const std::wstring& type, const Element& element); 
    6868 
    6969        OptionsManager(void); 
  • capture-hpc/branches/dev/capture-client/RegistryMonitor.cpp

    r360 r361  
    8989RegistryMonitor::RegistryMonitor(void) 
    9090{ 
    91         running = false; 
     91        m_Running = false; 
    9292 
    9393        std::wstring exclusion_list_path = L"RegistryMonitor.exl"; 
     
    184184        } 
    185185 
    186         if( !running ) 
     186        if( !m_Running ) 
    187187        { 
    188188                registry_monitor_thread = new Thread( this, false ); 
    189189                registry_monitor_thread->start(); 
    190                 running = true; 
     190                m_Running = true; 
    191191        } 
    192192} 
     
    200200        } 
    201201 
    202         if( running ) 
     202        if( m_Running ) 
    203203        {        
    204                 running = false; 
     204                m_Running = false; 
    205205                registry_monitor_thread->stop(); 
    206206                delete registry_monitor_thread; 
     
    369369RegistryMonitor::onUpdate( Observable<KernelEventVector, SystemEvent>& kernel_event_vector, SystemEvent& system_event ) 
    370370{ 
     371 
     372        //system_event.setData("registry-type", GetRegistryEventType(system_event.getData<unsigned int>("registry-type"))); 
    371373        //std::wstring registry_event_type = getRegistryEventType( system_event.getValue<unsigned int>( "registry-type" ) ); 
    372374        //std::wstring registry_path = getRegistryPath( system_event.getValue<std::wstring>( "registry-path" ) ); 
     
    391393        unsigned long bytes_received = 0; 
    392394 
    393         while( running ) 
     395        while(m_Running) 
    394396        { 
    395397                float capacity = kernel_event_vector->retrieveEvents(); 
  • capture-hpc/branches/dev/capture-client/Server.cpp

    r352 r361  
    2323 */ 
    2424#include "Server.h" 
    25 //#include "Xml.h" 
    26 //#include "XmlElement.h" 
    27  
    28  
    29  
    3025#include "Log.h" 
    3126#include "EventManager.h" 
     
    3934Server::Server(const std::wstring& server_address_string ) 
    4035{ 
     36        server_socket = INVALID_SOCKET; 
     37 
    4138        // Set the default port 
    4239        server_port = L"7070"; 
     
    104101        ADDRINFOW* address_info = NULL; 
    105102 
     103        reconnect_count++; 
     104 
    106105        ZeroMemory(&address_info_hints, sizeof(address_info_hints)); 
    107106 
     
    112111 
    113112        // Find the IPv4 address of the server 
    114         if ( ( GetAddrInfoW( server_address.c_str(), server_port.c_str(), &address_info_hints, &address_info ) ) == 0 ) 
    115         { 
    116                 sockaddr_in *socket_address = (struct sockaddr_in *) address_info->ai_addr; 
    117  
     113        if ( ( GetAddrInfoW( server_address.c_str(), server_port.c_str(), &address_info_hints, &address_info ) ) != 0 ) 
     114        { 
     115                return false; 
     116        } 
     117 
     118        sockaddr_in *socket_address = (struct sockaddr_in *) address_info->ai_addr; 
     119 
     120        server_socket = socket(address_info->ai_family, address_info->ai_socktype, address_info->ai_protocol); 
     121 
     122        if(server_socket !=  INVALID_SOCKET) 
     123        { 
    118124                // Connect the the server 
    119125                if( connect( server_socket, (sockaddr*)socket_address, (int)address_info->ai_addrlen ) != SOCKET_ERROR ) 
     
    121127                        reconnected = true; 
    122128                } 
    123  
    124                 FreeAddrInfoW( address_info ); 
    125         } 
    126  
    127         reconnect_count++; 
     129                else 
     130                { 
     131                        LOG(ERROR, "Server: Connect error %i", WSAGetLastError()); 
     132                } 
     133        } 
     134 
     135        FreeAddrInfoW( address_info ); 
     136 
     137         
    128138 
    129139        return reconnected; 
     
    195205Server::sendData() 
    196206{ 
     207        int result = 0; 
     208        Buffer sendBuffer; 
     209 
    197210        // Send all queued data 
    198211        while( !send_queue.empty() ) 
     
    201214                 
    202215                std::wstring& data = send_queue.front(); 
     216 
     217                bool converted = StringHelper::WideStringToMultiByteString(data, sendBuffer); 
     218 
     219                if(converted) 
     220                { 
     221                        result = send( server_socket, sendBuffer.GetBuffer(), sendBuffer.GetBufferSize(), 0 ); 
     222                } 
     223 
    203224                send_queue.pop_front(); 
    204225 
    205226                LeaveCriticalSection( &send_queue_lock ); 
    206227 
    207                 int result = send( server_socket, (char*)data.c_str(), data.length()*sizeof(wchar_t), 0 ); 
    208  
    209228                if( result == SOCKET_ERROR ) 
    210229                { 
    211                         LOG(ERR, "Server: Send error - %08x", WSAGetLastError() ); 
     230                        LOG(ERR, "Server: Send error - %i", WSAGetLastError() ); 
    212231                        EnterCriticalSection( &send_queue_lock ); 
    213232                        send_queue.push_front( data ); 
     
    218237                else 
    219238                { 
    220                         LOG(INFO, "Server: Sent %i bytes" ); 
     239                        LOG(INFO, "Server: Sent %i bytes", result); 
    221240                } 
    222241        } 
  • capture-hpc/branches/dev/capture-client/StringHelper.cpp

    r352 r361  
    11#include "StringHelper.h" 
     2#include <windows.h> 
    23 
    34std::wstring  
     
    1718} 
    1819 
     20bool StringHelper::WideStringToMultiByteString(const std::wstring &wideString, Buffer &mbString) 
     21{ 
     22        int size = WideCharToMultiByte(CP_UTF8, 0, wideString.c_str(), static_cast<int>(wideString.length()), NULL, 0, NULL, NULL); 
     23         
     24        if (size == 0 || !mbString.AllocateBuffer(size)) 
     25                return false; 
     26 
     27        int converted = WideCharToMultiByte(CP_UTF8, 0, wideString.c_str(), static_cast<int>(wideString.length()), mbString.GetBuffer(), size, NULL, NULL); 
     28 
     29        _ASSERT(size == converted); 
     30        return true; 
     31} 
     32 
    1933int 
    2034StringHelper::wideStringToInt(const wchar_t* wide_string) 
  • capture-hpc/branches/dev/capture-client/StringHelper.h

    r352 r361  
    11#pragma once 
    22#include <string> 
     3 
     4class Buffer 
     5{ 
     6public: 
     7        Buffer() 
     8                : m_Buffer(NULL), m_Size(0) 
     9        { 
     10        } 
     11        ~Buffer() 
     12        { 
     13                if(m_Buffer) 
     14                { 
     15                        free(m_Buffer); 
     16                } 
     17        } 
     18 
     19        bool AllocateBuffer(unsigned int size) 
     20        { 
     21                if(m_Buffer && size > m_Size) 
     22                { 
     23                        free(m_Buffer); 
     24                } 
     25                m_Buffer = (char*)malloc(size); 
     26                if(m_Buffer) 
     27                        m_Size = size; 
     28                return (m_Buffer != NULL); 
     29        } 
     30 
     31        char* GetBuffer()                               { return m_Buffer; } 
     32        unsigned int GetBufferSize()    { return m_Size; } 
     33 
     34public: 
     35        char*                   m_Buffer; 
     36        unsigned int    m_Size; 
     37}; 
    338 
    439class StringHelper 
     
    641public: 
    742        static std::wstring multiByteStringToWideString(const char* string, size_t length); 
     43        static bool WideStringToMultiByteString(const std::wstring& string, Buffer& mbString);  
    844 
    945        // NOTE maybe we should be using boost::lexical_cast for all of these 
  • capture-hpc/branches/dev/capture-client/SystemEvent.cpp

    r352 r361  
    11#include "SystemEvent.h" 
     2 
     3CRC crc32(const char *buf) 
     4{ 
     5        int size = 0; 
     6        unsigned long crc = (unsigned long)~0; 
     7        char c = 0; 
     8        while(c = buf[size++]) 
     9                _CRC32_(crc, c); 
     10        //char *p; 
     11        //size_t len, nr; 
     12 
     13        //len = 0; 
     14        //nr=size; 
     15        //for (len += nr, p = buf; nr--; ++p) 
     16        //{ 
     17        //      _CRC32_(crc, *p); 
     18        //} 
     19        return ~crc; 
     20} 
     21 
     22CRC crc32w(const wchar_t *buf) 
     23{ 
     24        int size = 0; 
     25        unsigned long crc = (unsigned long)~0; 
     26        wchar_t c = 0; 
     27        while(c = buf[size++]) 
     28                _CRC32_(crc, c); 
     29        return ~crc; 
     30} 
    231 
    332//SystemEvent::SystemEvent(const std::wstring& eventName) 
  • capture-hpc/branches/dev/capture-client/SystemEvent.h

    r360 r361  
    22#include "Variant.h" 
    33#include <map> 
     4#include <hash_map> 
     5 
     6/* 
     7 * This code implements the AUTODIN II polynomial 
     8 * The variable corresponding to the macro argument "crc" should 
     9 * be an unsigned long. 
     10 * Original code  by Spencer Garrett <[email protected]> 
     11 */ 
     12 
     13#define _CRC32_(crc, ch)         (crc = (crc >> 8) ^ crc32tab[(crc ^ (ch)) & 0xff]) 
     14 
     15/* generated using the AUTODIN II polynomial 
     16 *      x^32 + x^26 + x^23 + x^22 + x^16 + 
     17 *      x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x^1 + 1 
     18 */ 
     19extern "C" { 
     20static const unsigned long crc32tab[256] = { 
     21        0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 
     22        0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 
     23        0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 
     24        0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 
     25        0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 
     26        0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 
     27        0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 
     28        0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, 
     29        0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 
     30        0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 
     31        0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 
     32        0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 
     33        0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 
     34        0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, 
     35        0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 
     36        0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 
     37        0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 
     38        0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, 
     39        0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 
     40        0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, 
     41        0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 
     42        0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 
     43        0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 
     44        0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 
     45        0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 
     46        0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 
     47        0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 
     48        0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 
     49        0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 
     50        0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, 
     51        0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 
     52        0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 
     53        0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 
     54        0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 
     55        0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 
     56        0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 
     57        0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 
     58        0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, 
     59        0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 
     60        0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 
     61        0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 
     62        0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 
     63        0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 
     64        0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, 
     65        0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 
     66        0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 
     67        0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 
     68        0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 
     69        0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 
     70        0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, 
     71        0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 
     72        0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 
     73        0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 
     74        0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, 
     75        0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 
     76        0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 
     77        0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 
     78        0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 
     79        0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 
     80        0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 
     81        0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 
     82        0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, 
     83        0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 
     84        0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d, 
     85}; 
     86 
     87 
     88 
     89typedef unsigned long CRC; 
     90 
     91CRC crc32(const char *buf); 
     92CRC crc32w(const wchar_t *buf); 
     93//{ 
     94//      int size = 0; 
     95//      unsigned long crc = (unsigned long)~0; 
     96//      char c = 0; 
     97//      while(c = buf[size++]) 
     98//              _CRC32_(crc, c); 
     99//      //char *p; 
     100//      //size_t len, nr; 
     101// 
     102//      //len = 0; 
     103//      //nr=size; 
     104//      //for (len += nr, p = buf; nr--; ++p) 
     105//      //{ 
     106//      //      _CRC32_(crc, *p); 
     107//      //} 
     108//      return ~crc; 
     109//} 
     110}; 
     111 
     112 
    4113 
    5114class SystemEvent 
     
    18127                } 
    19128                event_data.clear(); 
     129        } 
     130 
     131        SystemEvent(const SystemEvent& e) 
     132        { 
     133                _ASSERT(false); // Shouldn't really be copying these about 
     134                event_data = e.event_data; 
     135        } 
     136 
     137        SystemEvent& operator=(const SystemEvent& e) 
     138        { 
     139                _ASSERT(false); // Shouldn't really be copying these about 
     140                if(this != &e) 
     141                { 
     142                        event_data = e.event_data; 
     143                } 
     144                return *this; 
    20145        } 
    21146 
  • capture-hpc/branches/dev/capture-client/Thread.cpp

    r352 r361  
    3939        if( thread_handle != INVALID_HANDLE_VALUE) 
    4040        { 
    41                 runnable_object->running = false; 
     41                runnable_object->m_Running = false; 
    4242 
    4343                // If we are allowed to forcefull terminate the thread do so 
     
    6464        Thread* thread = (Thread*)thread_object_ptr; 
    6565         
    66         thread->runnable_object->running = true; 
     66        thread->runnable_object->m_Running = true; 
    6767 
    6868        thread->runnable_object->run(); 
  • capture-hpc/branches/dev/capture-client/Thread.h

    r352 r361  
    4343        virtual void run() = 0; 
    4444protected: 
    45         bool running; 
     45        bool m_Running; 
    4646}; 
    4747 
  • capture-hpc/branches/dev/capture-client/Variant.cpp

    r360 r361  
    109109} 
    110110 
     111void  Variant::get(Variant& value) { value = *this; } 
    111112void Variant::get(float& value) { value = float_value; } 
    112113void Variant::get(int& value) { value = integer_value; } 
  • capture-hpc/branches/dev/capture-client/Variant.h

    r360 r361  
    5656{ 
    5757public: 
     58        Variant() 
     59        { 
     60        } 
     61 
    5862        template<typename T> 
    5963        Variant(const T& v) 
     64        { 
     65                set(v); 
     66        } 
     67 
     68        Variant(const Variant& v) 
    6069        { 
    6170                set(v); 
     
    94103        void set(const Variant& value); 
    95104 
     105        void get(Variant& value); 
    96106        void get(float& value); 
    97107        void get(int& value); 
  • capture-hpc/branches/dev/capture-client/Visitor.cpp

    r352 r361  
    1717#include <boost/bind.hpp> 
    1818 
    19 //<string::iterator> 
     19#include "Log.h" 
     20#include "EventManager.h" 
    2021 
    2122Visitor::Visitor(void) 
    22 { 
    23         printf("here"); 
    24         DebugPrintTrace(L"Visitor::Visitor(void) start\n"); 
     23{        
     24        LOG(INFO, "Visitor: Start"); 
     25        m_Visiting = false; 
     26 
     27        loadClientPlugins(); 
    2528         
    26         visiting = false; 
    27  
    28         hQueueNotEmpty = CreateEvent(NULL, FALSE, FALSE, NULL); 
    29  
    30         //onServerEventConnection = EventController::getInstance()->connect_onServerEvent(L"visit-event", boost::bind(&Visitor::onServerEvent, this, _1)); 
    31         //EventController::getInstance()->attach(L"url-group", this); 
    32  
    33         loadClientPlugins(); 
     29        EventManager::getInstance()->attach<Visitor>(L"visit-event", this, &Visitor::onServerEvent); 
    3430 
    3531        visitorThread = new Thread(this); 
    3632        visitorThread->start(); 
    37         DebugPrintTrace(L"Visitor::Visitor(void) end\n"); 
    3833} 
    3934 
    4035Visitor::~Visitor(void) 
    4136{ 
    42         DebugPrintTrace(L"Visitor::~Visitor(void) start\n"); 
    43         CloseHandle(hQueueNotEmpty); 
     37        LOG(INFO, "Visitor: Stopping"); 
     38 
     39        m_Running = false; 
     40 
     41        // Clear the queue and wake up the visitor thread if it 
     42        // is waiting for a visit event to be queued. This allows 
     43        // the thread to exit correctly and release its resources 
     44        m_VisitQueue.Clear(true); 
     45 
    4446        unloadClientPlugins(); 
    45  
    46         DebugPrintTrace(L"Visitor::~Visitor(void) end\n"); 
    47         // TODO free items in toVisit queue 
    4847} 
    4948 
     
    5251{ 
    5352        try { 
    54                 DebugPrintTrace(L"Visitor::run() start\n"); 
    55                 while(true) 
    56                 { 
    57                         WaitForSingleObject(hQueueNotEmpty, INFINITE); 
    58                         VisitEvent* visitEvent = toVisit.front(); 
    59                         toVisit.pop(); 
    60                         visiting = true; 
    61  
    62                         DebugPrintTrace(L"Visitor::run() getting App plugin\n"); 
    63                         ApplicationPlugin* applicationPlugin = getApplicationPlugin(visitEvent->getProgram()); 
    64                          
     53 
     54                while(m_Running) 
     55                { 
     56                        VisitEvent* visitEvent = NULL; 
     57                        m_Visiting = m_VisitQueue.Pop(visitEvent); 
     58 
     59                        if(!m_Visiting) 
     60                                continue; 
     61 
     62                        LOG(INFO, "Visitor: Start visiting"); 
     63                        ApplicationPlugin* applicationPlugin = getApplicationPlugin(visitEvent->getProgram());                   
    6564 
    6665                        _ASSERT(applicationPlugin != NULL); 
    67                         DebugPrintTrace(L"Visitor::run() got App plugin\n"); 
     66 
    6867                        if(applicationPlugin) 
    6968                        { 
    70                                 DebugPrint(L"Visitor::run() setting algorithm\n"); 
     69 
    7170                                visitEvent->setAlgorithm(applicationPlugin->getAlgorithm()); 
    7271 
    73                                 DebugPrintTrace(L"Visitor::run() notify prestart\n"); 
     72         
    7473                                //notify(CAPTURE_VISITATION_PRESTART, *visitEvent); 
    7574 
    76                                 DebugPrintTrace(L"Visitor::run() notify start\n"); 
     75 
    7776                                //notify(CAPTURE_VISITATION_START, *visitEvent); 
    7877 
     
    8180                                try 
    8281                                { 
    83                                         DebugPrintTrace(L"Visitor::run() visit group start\n"); 
     82                                        LOG(INFO, "Visitor: Plugin starting visiting"); 
    8483                                        applicationPlugin->visitGroup(visitEvent); 
    85                                         DebugPrintTrace(L"Visitor::run() visit group end\n"); 
     84                                        LOG(INFO, "Visitor: Plugin finished visiting"); 
    8685                                }  
    8786                                catch (...) 
     
    9493                                if(visitEvent->isError()) 
    9594                                { 
    96                                         DebugPrintTrace(L"Visitor::run() notify visitEvent isError\n"); 
    9795                                        //notify(visitEvent->getErrorCode(), *visitEvent); 
    9896                                } else { 
    99                                         DebugPrintTrace(L"Visitor::run() notify visitiation finish\n"); 
    10097                                        //notify(CAPTURE_VISITATION_FINISH, *visitEvent); 
    10198                                } 
    10299 
    103                                 DebugPrintTrace(L"Visitor::run() notify postfinish\n"); 
    104100                                //notify(CAPTURE_VISITATION_POSTFINISH, *visitEvent); 
    105101                        } 
    106102 
    107103                        delete visitEvent; 
    108                         visiting = false; 
    109                         DebugPrintTrace(L"Visitor::run() end\n"); 
     104                        m_Visiting = false; 
     105                        LOG(INFO, "Visitor: Finished visiting"); 
    110106                } 
    111107        } catch (...) { 
    112                 printf("Visitor::run exception\n");      
    113108                throw; 
    114109        } 
     
    247242 
    248243Url* 
    249 Visitor::createUrl(const std::vector<Attribute>& attributes) 
    250 { 
    251         DebugPrintTrace(L"Visitor::createUrl(const std::vector<Attribute>& attributes) start\n"); 
     244Visitor::createUrl(const Element& urlElement) 
     245{ 
    252246        std::wstring url; 
    253247        std::wstring program; 
    254248        int time = 0; 
    255         for each(Attribute attribute in attributes) 
    256         { 
    257                 if(attribute.getName() == L"url") { 
    258                         url = attribute.getValue(); 
    259                 } else if(attribute.getName() == L"program") { 
    260                         program = attribute.getValue(); 
    261                 } else if(attribute.getName() == L"time") { 
    262                         time = boost::lexical_cast<int>(attribute.getValue()); 
    263                 } 
    264         } 
    265         DebugPrintTrace(L"Visitor::createUrl(const std::vector<Attribute>& attributes) end\n"); 
     249 
     250        const AttributeMap& attributes = urlElement.GetAttributes(); 
     251 
     252        for(AttributeMap::const_iterator it = attributes.begin(); it != attributes.end(); it++) 
     253        { 
     254                if(it->first == L"url")  
     255                { 
     256                        url = it->second; 
     257                } 
     258                else if(it->first == L"program")  
     259                { 
     260                        program = it->second; 
     261                } 
     262                else if(it->first == L"time")  
     263                { 
     264                        time = boost::lexical_cast<int>(it->second); 
     265                } 
     266 
     267        } 
    266268        return new Url(Url::decode(url), program, time); 
    267269} 
    268270 
    269271void 
    270 Visitor::onServerEvent(const Element& element) 
    271 { 
    272         DebugPrintTrace(L"Visitor::onServerEvent(const Element& element) start\n"); 
     272Visitor::onServerEvent(const std::wstring& eventType, const Element& receivedEvent) 
     273{ 
     274        if(receivedEvent.GetName() != L"visit-event") 
     275        { 
     276                LOG(WARN, "Visitor: Received unhandled event - %s", receivedEvent.GetName()); 
     277                return; 
     278        } 
     279 
     280        LOG(INFO, "Visitor: Received visit event"); 
     281         
     282        const std::wstring& program = receivedEvent.GetAttribute(L"program"); 
     283        const std::wstring& identifier = receivedEvent.GetAttribute(L"identifier"); 
     284        int visitTime = boost::lexical_cast<int>(receivedEvent.GetAttribute(L"time")); 
     285 
     286        const ChildElementList& urls = receivedEvent.GetChildElements(); 
     287 
     288        if(urls.size() == 0) 
     289                return; 
     290 
    273291        VisitEvent* visitEvent = new VisitEvent(); 
    274  
    275         if(element.getName() == L"visit-event") { 
    276                 // A url event with multiple urls to visit 
    277                 std::wstring identifier = element.getAttributeValue(L"identifier"); 
    278                 std::wstring program = element.getAttributeValue(L"program"); 
    279                 int visitTime = boost::lexical_cast<int>(element.getAttributeValue(L"time")); 
     292        if(!visitEvent) 
     293                return;  
     294 
     295        for(ChildElementList::const_iterator it = urls.begin(); it != urls.end(); it++) 
     296        { 
     297                Element* urlElement = (*it); 
    280298                 
    281                 visitEvent->setIdentifier(identifier); 
    282                 visitEvent->setProgram(program); 
    283  
    284                 for each(Element* e in element.getChildElements()) 
    285                 { 
    286                         if(e->getName() == L"item") 
    287                         { 
    288                                 Url* url = createUrl(e->getAttributes()); 
    289                                 // Force the visit time and program to the url event just in case 
    290                                 // some supplied them in the item element 
    291                                 url->setVisitTime(visitTime); 
    292                                 url->setProgram(program); 
    293                                 visitEvent->addUrl(url); 
    294                         } 
    295                 }        
    296         } 
    297  
    298         if(visitEvent->getUrls().size() > 0) 
    299         { 
    300                 toVisit.push(visitEvent); 
    301                 SetEvent(hQueueNotEmpty); 
    302         } else { 
    303                 printf("Visitor-onServerEvent: ERROR no url specified for visit event\n"); 
    304                 delete visitEvent; 
    305         } 
    306         DebugPrintTrace(L"Visitor::onServerEvent(const Element& element) end\n"); 
    307 } 
     299                if(urlElement->GetName() != L"item") 
     300                        continue; 
     301 
     302                Url* url = createUrl(*urlElement); 
     303 
     304                if(url) 
     305                { 
     306                        // Force the visit time and program to the url event just in case 
     307                        // some supplied them in the item element 
     308                        url->setVisitTime(visitTime); 
     309                        url->setProgram(program); 
     310                        visitEvent->setProgram(program); 
     311                        visitEvent->addUrl(url); 
     312                } 
     313        } 
     314 
     315        LOG(INFO, "Visitor: Queued visit event %s", identifier); 
     316        m_VisitQueue.Push(visitEvent);   
     317} 
  • capture-hpc/branches/dev/capture-client/Visitor.h

    r352 r361  
    3232#include <hash_map> 
    3333#include <boost/signal.hpp> 
     34#include "BlockingQueue.h" 
    3435 
    3536class Url; 
     
    5859        void loadClientPlugins(); 
    5960        void unloadClientPlugins(); 
    60         Url* createUrl(const std::vector<Attribute>& attributes); 
     61        Url* createUrl(const Element& urlElement); 
    6162        ApplicationPlugin* getApplicationPlugin(const std::wstring& applicationName); 
    6263 
    6364        void run(); 
    6465 
    65         void onServerEvent(const Element& element); 
     66        void onServerEvent(const std::wstring& eventType, const Element& element); 
    6667 
    6768        ApplicationPlugin* createApplicationPluginObject(HMODULE hPlugin); 
     
    6970        boost::signals::connection onServerEventConnection; 
    7071 
    71         HANDLE hQueueNotEmpty; 
    72         bool visiting; 
    73         std::queue<VisitEvent*> toVisit; 
     72        bool    m_Visiting; 
     73        BlockingQueue<VisitEvent*, 256>         m_VisitQueue; 
     74         
     75 
    7476        Thread* visitorThread; 
    7577        stdext::hash_map<HMODULE, std::list<ApplicationPlugin*>*> applicationPlugins;